ďťż
 
[mssql] Wynik z zapytania ďťż
 
[mssql] Wynik z zapytania
Zobacz wiadomości
 
Cytat
A gdyby tak się wedrzeć na umysłów górę, / Gdyby stanąć na ludzkich myśli piramidzie, / I przebić czołem przesądów chmurę, / I być najwyższą myślą wcieloną. . . Juliusz Słowacki, Kordian
Indeks BCB i MySQL subiekt gt fototapeta
 
  Witamy

[mssql] Wynik z zapytania



panczo - 02-02-2007 00:09
[mssql] Wynik z zapytania
  Witam

mam pewien problem natury technicznej i wydajnosciowej.

Jest baza, z ktorej wyciagam informacje na temat poszczegolnych
produktow i firm poprzez wywolanie zapytania z aplikacji:

SELECT * FROM TAB WHERE dane LIKE 'costam'
ORDER BY priorytet, firma, dane

wiersz | dane | firma | priorytet
1 | aaa | F1 | 1
2 | aaab | F1 | 1
2 | aaabb | F1 | 1
4 | bbb | F3 | 2
5 | bbbc | F3 | 2
6 | ccc | F2 | 3
7 | cccd | F2 | 3
8 | ccccdd | F2 | 3
9 | ccccddd | F2 | 3
itd.

Istnieje zmienna, ktora odpowiada za ilosc zwroconych wierszy (maxRows)
i ilosc wierszy z kazdej z firm (firmRows).

Przykladowo jesli firmRows = 1, a maxRows = 3 to wynik bedzie mial
nastepujaca postac:

wiersz | dane | firma | priorytet
1 | aaa | F1 | 1
2 | bbb | F3 | 2
3 | ccc | F2 | 3

Na razie wyglada to tak, ze caly wynik jest zwracany do aplikacji, tam
jest odpowiednio sortowany, tworzone sa tablice z indeksami (np.: gdzie
zaczynaja sie wiersze dla danej firmy, ile ich jest, itp.), a nastepnie
ostateczny wynik.

Idea bylo przeniesienie sortowania i budowania wyniku do bazy danych, z
nadzieja na poprawe szybkosci. Tutaj pojawil sie problem, mianowicie jak
najoptymalniej zbudowac taki rezultat?

Moj pomysl na to jest taki:

SELECT TOP 20 * FROM
(
SELECT TOP 4 * FROM tab WHERE dane LIKE 'costam' AND firma = 'F1' ORDER
BY priorytet, firma, dane

UNION

SELECT TOP 4 * FROM tab WHERE dane LIKE 'costam' AND firma = 'F2' ORDER
BY priorytet, firma, dane

UNION

SELECT TOP 4 * FROM tab WHERE dane LIKE 'costam' AND firma = 'F3' ORDER
BY priorytet, firma, dane
) AS temp

Tyle tylko, ze to rozwiazanie nie jest optymalne i dodajac dynamicznie
kolejne firmy czas dla kazdego z SELECT sie sumuje i osiaga duze
wartosci. Innym mogloby byc tworzenie tabeli tymczasowej lub uzycie juz
istniejacej do wstawiania, sortowania i pobierania potrzebnych danych,
co rowniez nie jest dobrym rozwiazaniem z uwagi na czestosc i
rownoleglosc mozliwych zapytan. Czy jest mozliwosc dynamicznego
budowania rezultatu poprzez kursor w procedurze?

Dzieki za wszelkie informacje
panczo





Marcin A. Guzowski - 02-02-2007 00:09

  panczo napisał(a):
> Witam
>
> mam pewien problem natury technicznej i wydajnosciowej.

Zanim się wypowiem chciałbym poznać wersję SQL Servera - może to mieć
spore znaczenie.

--
Pozdrawiam,
Marcin Guzowski
http://guzowski.info




panczo - 03-02-2007 00:01

  Marcin A. Guzowski napisał(a):
> panczo napisał(a):
>> Witam
>>
>> mam pewien problem natury technicznej i wydajnosciowej.
>
>
> Zanim się wypowiem chciałbym poznać wersję SQL Servera - może to mieć
> spore znaczenie.
>
>

Rozwiazanie ma pracowac w wersjach 2000 i 2005.

Pozdrawiam
panczo




Marcin A. Guzowski - 03-02-2007 00:02

  panczo napisał(a):
> Rozwiazanie ma pracowac w wersjach 2000 i 2005.

Jeśli więc rozwiązanie ma być spójne, to funkcjonalności, jakie można
wykorzystać, są niestety ograniczone do tych dostępnych w wersji 2000.

W tej sytuacji bez iteracyjności (kursora lub pętli WHILE) się pewnie
nie obejdzie.

Spróbowałbym więc napisać procedurę, która w pętli WHILE (obracającej
się (maxRows/firmRows) razy) dorzucałaby do zmiennej tabelarycznej TOP
firmRows wierszy (konieczny dynamiczny SQL) zawężonych odpowiednim
WHERE*.
[*] Od razu jedna uwaga:
Z tego co widzę, w całym rozwiązaniu występować ma operator LIKE. Jest
on stosunkowo kosztowny i w zależności od jego selektywności (ile
wierszy zawęża jako kryterium SELECTa) trzeba przyjąć jedną ze
strategii - albo wrzucić cały potencjalny rezultat do struktury
tymczasowej w procedurze i dalej pracować na niej - albo za każdym
obrotem pętli WHILE w warunku WHERE stosować też LIKEa. Problemem może
być też identyfikator firmy w warunku WHERE, ale da się to też
rozwiązać na kilka sposobów.

Każdy obrót pętli wrzuci więc do zmiennej tabelarycznej docelową
liczbę wierszy z danej firmy. Jeżeli dobrze zrozumiałem, to sprawa
załatwiona. Teraz wystarczy tylko zwrócić odpowiednio posortowany
resultset ze zmiennej tabelarycznej.

--
Pozdrawiam,
Marcin Guzowski
http://guzowski.info
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • effulla.pev.pl
  • comp
    Oracle, SQL, PL/SQL. Jak =?ISO-8859-2?Q?napisa=E6_zapytanie=2C?==?ISO-8859-2?Q?_kt=F3re_zwr=F3ci_nazw=EA_atrybutu=2C_kt=F3reg o?==?ISO-8859-2?Q?_warto=B6ci_spe=B3niaj=B1_zadany_warunek?= =?ISO-8859-2?Q?Narz=EAdzie_do_budowania_zapyta=F1_SQL=2C?==?I SO-8859-2?Q?_PL/PgSQL=2C_PL/SQL=2C_T-SQL?= [ms sql] =?ISO-8859-2?Q?wy=B6wietlenie_pierwszych_5_rekord?==?ISO-8859-2?Q?=F3w_z_zapytania_=3F_odpowiednik_ROWNUM_w_o?== ?ISO-8859-2?Q?raclu_dla_MS_SQL=27a?= phpMyAdmin zadaje =?ISO-8859-2?Q?z=B3e_zapytania=2E=2E=2E_Dl?==?ISO-8859-2?Q?aczego=3F?= [MSSQL2000] Problem z =?ISO-8859-2?Q?tabel=B1/indeksem/zapytanie?==?ISO-8859-2?Q?m_czy_b=B3=B1d_w_bazie_danych=2E=2E=2E?= [oracle] zapytanie dynamiczne z =?ISO-8859-2?Q?=22dynamiczn=B1_?==?ISO-8859-2?Q?nazw=B1_tabeli=22?= [mysql/php] jak =?ISO-8859-2?Q?zliczy=E6_ilo=B6=E6_unikalnyc?==?ISO-8859-2?Q?h_rekord=F3w_w_jednym_zapytaniu=3F?= [MySQL] Zapytanie z =?ISO-8859-2?Q?dw=F3ch_tabel_na_raz_?==?ISO-8859-2?Q?i_grupowanie_po_wsp=F3lnym_polu=2E_Jak_=3F?= mecze sie i mecze i nic - zapytanie czesciowe [sql][pgsql] zapytanie sql
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • autwywalczyl.opx.pl
  • Cytat

    Decede mihi sole - nie zasłaniaj mi słonca.
    Gdy kogoś kochasz, jesteś jak stworzyciel świata - na cokolwiek spojrzysz, nabiera to kształtu, wypełnia się barwą, światłem. Powietrze przytula się do ciebie, choćby był mróz, a ty masz w sobie tyle radości, że musisz ją rozdawać wokoło, bo się w tobie nie mieści
    Hoc fac - tak czyń.
    A tergo - od tyłu; z tyłu.
    I czarne włosy posiwieją. Safona

    Valid HTML 4.01 Transitional

    Free website template provided by freeweblooks.com