[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.pldoc.pisz.plpdf.pisz.pleffulla.pev.pl
|
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.pldoc.pisz.plpdf.pisz.plautwywalczyl.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 |
|