Sortowanie tabel
Lucek B - 06-08-2006 02:18
Sortowanie tabel
Witam Przepraszam z góry za pytanie początkującego , dopiero poznaję zagadnienia zwiazane z bazami. Mam pytanie projektowe . Moja baza bedzie zaawierała kilka nieskomplikowanych tabel z kilkoma polami.Uzytkownik bedzie mial program ktorego elementem jest tabela ktora pozwala mu na przewijanie co N rekordow w partiach np co 10 (np od 20 do 30).Bedzie tez mogl posortowac wedlug kazdej kategorii ale juz globalnie np po kolei znowu transzami co 10 jednak wyniki beda posortowane np malejaco. I tak po kazdej kategorii. I tu mam pytanie.Otoz rekordow bedzie nie mniej niz 5000 i oczywiscie nie moge sobie pozowolic na "przestoj". Jak to powinienem wykonac ? CZy gdy user wykona sortowanie to mam wykonac SELECT , posortowac , zwrocic porcje danych ? Wyglada mi to na 100% marnowanie pamieci i czasu.Prosze o podpowiedz. Czy w bazami sa zwiazane jakies ogolno dostepne desing patterny ? Jezeli tak to prosze o namiary. Z góry dzieki.
Pozdrawiam Lucek
-- Wysłano z serwisu OnetNiusy: http://niusy.onet.pl
Artur Gancarz - 06-08-2006 02:18
Użytkownik Lucek B napisał: > Witam > Przepraszam z góry za pytanie początkującego , dopiero poznaję zagadnienia > zwiazane z bazami. > Mam pytanie projektowe . Moja baza bedzie zaawierała kilka nieskomplikowanych > tabel z kilkoma polami.Uzytkownik bedzie mial program ktorego elementem jest > tabela ktora pozwala mu na przewijanie co N rekordow w partiach np co 10 (np od > 20 do 30).Bedzie tez mogl posortowac wedlug kazdej kategorii ale juz globalnie > np po kolei znowu transzami co 10 jednak wyniki beda posortowane np malejaco. > I tak po kazdej kategorii. > I tu mam pytanie.Otoz rekordow bedzie nie mniej niz 5000 i oczywiscie nie moge > sobie pozowolic na "przestoj". Jak to powinienem wykonac ? CZy gdy user wykona > sortowanie to mam wykonac SELECT , posortowac , zwrocic porcje danych ? > Wyglada mi to na 100% marnowanie pamieci i czasu.Prosze o podpowiedz. > Czy w bazami sa zwiazane jakies ogolno dostepne desing patterny ? Jezeli tak > to prosze o namiary. > Z góry dzieki. > > Pozdrawiam Lucek > > > Niestety nie jestem expertem i nie jestem pewien, czy zrozumiałem Twoje pytanie, ale: 1) jeśli chcesz posortować wyniki otrzymywane z bazy to np.: select * from tabela order by nazwa_kolumny_sortowanej; Zwróci wtedy posortowane wiersze wg podanej nazwy kolumny.
2) jeśli chcesz np. otrzymać na podstawie poprzedniego zapytania rekordy np. od 21 do 30 (dokładnie 10 szt.) to trzeba na końcu dopisać: select * from tabela order by nazwa_kolumny_sortowanej limit 20,10;
Oznacza to mniej więcej to, że ma pominąć 20 szt. z początku, a następnie wyświetlić 10 następnych (tutaj: od 21 do 30) i tak dalej: select * from tabela order by nazwa_kolumny_sortowanej limit 0,10; wyświetli rekordy od 1 do 10 (pominie ZERO)
select * from tabela order by nazwa_kolumny_sortowanej limit 120,10; wyświetli rekordy od 121 do 130
Czy o to chodziło? pozdrawiam Artur
lbohme@vp.pl - 06-08-2006 02:18
> Niestety nie jestem expertem i nie jestem pewien, czy zrozumiałem Twoje > pytanie, ale: > 1) jeśli chcesz posortować wyniki otrzymywane z bazy to np.: > select * from tabela order by nazwa_kolumny_sortowanej; > Zwróci wtedy posortowane wiersze wg podanej nazwy kolumny. > > 2) jeśli chcesz np. otrzymać na podstawie poprzedniego zapytania rekordy > np. od 21 do 30 (dokładnie 10 szt.) to trzeba na końcu dopisać: > select * from tabela order by nazwa_kolumny_sortowanej limit 20,10; > > Oznacza to mniej więcej to, że ma pominąć 20 szt. z początku, a > następnie wyświetlić 10 następnych (tutaj: od 21 do 30) > i tak dalej: > select * from tabela order by nazwa_kolumny_sortowanej limit 0,10; > wyświetli rekordy od 1 do 10 (pominie ZERO) > > select * from tabela order by nazwa_kolumny_sortowanej limit 120,10; > wyświetli rekordy od 121 do 130 > > Czy o to chodziło? > pozdrawiam > Artur
Dzieki za odpowiedz. Widziałem to rozwiązanie jednak rozwazam je w kontekscie sortowania globalnego czyli wszystkich rekordów w bazie.Podany kod posortuje te 10 wierszy(dobrze rozumuje?)a nie o tym mysle. Przedstawie to na przykladzie np prosta gra ktora posiada unikalne id ze skojarzonym wynikiem w pewnej grze internetowej
id score 1 222 .. 2 233
55 23 .. 355 3235 Teraz ktos posiada tabele w ktorej moze ogladnac 10 wynikow naraz Pobiera wyniki od 20 do 30. Szuka po id gry. Po chwili chce dostac posortowane wyniki ale nie ta porcje 10 tylko globalnie cala tabele czyli kto ma najwiecej punktow .Ja to widze tak - trzeba posortowac cala tabel w jednym zapytaniu i dostane wszystkie wiersze w dobrej kolejnosci , potem zeby nie wykonywac kolejnego zapytania zachowam to w pamieci przez pewien okres czasu i klient bedzie mogl odpytywac tak posortowane dane.Jest to jednak bardzo pamieciozerne i nieefektywne zatem zle zaprojektowlem.Jak to powinno wygladac ?? Ten przyklad to nie to co robie , bede mial rowniez porownanie ciagu znakow zatem posortowanie tego bedzie trwac znacznie dluzej. Moje pytanie wiec brzmi jak sie mam do tego porzadnie zabrac ??? Bardzo prosze o podpowiedz
Pozdrawiam Luccek
-- Wysłano z serwisu OnetNiusy: http://niusy.onet.pl
Bartosz Feński aka fEnIo - 06-08-2006 02:18
W artykule lbohme@vp.pl napisał(a):
>> Niestety nie jestem expertem i nie jestem pewien, czy zrozumiałem Twoje >> pytanie, ale: >> 1) jeśli chcesz posortować wyniki otrzymywane z bazy to np.: >> select * from tabela order by nazwa_kolumny_sortowanej; >> Zwróci wtedy posortowane wiersze wg podanej nazwy kolumny. >> >> 2) jeśli chcesz np. otrzymać na podstawie poprzedniego zapytania rekordy >> np. od 21 do 30 (dokładnie 10 szt.) to trzeba na końcu dopisać: >> select * from tabela order by nazwa_kolumny_sortowanej limit 20,10; >> >> Oznacza to mniej więcej to, że ma pominąć 20 szt. z początku, a >> następnie wyświetlić 10 następnych (tutaj: od 21 do 30) >> i tak dalej: >> select * from tabela order by nazwa_kolumny_sortowanej limit 0,10; >> wyświetli rekordy od 1 do 10 (pominie ZERO) >> >> select * from tabela order by nazwa_kolumny_sortowanej limit 120,10; >> wyświetli rekordy od 121 do 130 >> >> Czy o to chodziło? > Dzieki za odpowiedz. > Widziałem to rozwiązanie jednak rozwazam je w kontekscie sortowania > globalnego czyli wszystkich rekordów w bazie.Podany kod posortuje > te 10 wierszy(dobrze rozumuje?)a nie o tym mysle.
Źle rozumujesz.
> Przedstawie to na przykladzie np prosta gra ktora posiada unikalne id > ze skojarzonym wynikiem w pewnej grze internetowej > > id score > 1 222 > . > 2 233 > > 55 23 > . > 355 3235 > Teraz ktos posiada tabele w ktorej moze ogladnac 10 wynikow naraz > Pobiera wyniki od 20 do 30. Szuka po id gry. Po chwili chce dostac > posortowane wyniki ale nie ta porcje 10 tylko globalnie cala tabele czyli > kto ma najwiecej punktow .
Tak właśnie się stanie po zapytaniu, które przytoczył Ci poprzednik.
>Ja to widze tak - trzeba posortowac cala tabel > w jednym zapytaniu i dostane wszystkie wiersze w dobrej kolejnosci, potem > zeby nie wykonywac kolejnego zapytania zachowam to w pamieci przez pewien okres > czasu i klient bedzie mogl odpytywac tak posortowane dane.Jest to jednak > bardzo pamieciozerne i nieefektywne zatem zle zaprojektowlem.
Nigdy nie wyciągaj wszystkich rekordów. W 99% jest to błąd.
> Jak to powinno > wygladac ?? Ten przyklad to nie to co robie , bede mial rowniez porownanie > ciagu znakow zatem posortowanie tego bedzie trwac znacznie dluzej. > Moje pytanie wiec brzmi jak sie mam do tego porzadnie zabrac ??? > Bardzo prosze o podpowiedz
Bazy danych zostały zaprojektowane do takiego przetwarzania, by było one jak najbardziej optymalne i szybkie. Po prostu dobrze dobierz zapytanie tak by baza zwróciła taką ilość danych jaką chcesz w danym momencie wyświetlić.
Przetwarzanie tych danych dopiero po wyciągnięciu z bazy jest często gęsto nieporozumieniem i jest wolniejsze.
pozdr, fEnIo
-- ,''`. Bartosz Fenski | mailto:fenio@debian.org | pgp:0x13fefc40 | irc:fEnIo : :' : 32-050 Skawina - Glowackiego 3/15 - malopolskie v. - Poland `. `' phone:+48602383548 | proud Debian maintainer and user `- http://skawina.eu.org | jid:fenio@jabber.org | rlu:172001
lbohme@vp.pl - 06-08-2006 02:18
> > Bazy danych zostały zaprojektowane do takiego przetwarzania, by było one > jak najbardziej optymalne i szybkie. Po prostu dobrze dobierz zapytanie tak > by baza zwróciła taką ilość danych jaką chcesz w danym momencie wyświetlić. > > Przetwarzanie tych danych dopiero po wyciągnięciu z bazy jest często gęsto > nieporozumieniem i jest wolniejsze. > > pozdr, > fEnIo > > --
Powiem szczerze iz nie spodziewalem się tego W takim razie ogromny ukłon w strone autorów tych rozwiazan i Was za odpowiedzi na moje pytanie.Dzieki
Pozdrawiam Lucek
-- Wysłano z serwisu OnetNiusy: http://niusy.onet.pl
lost - 06-08-2006 02:18
> Powiem szczerze iz nie spodziewalem się tego W takim razie ogromny ukłon w > strone autorów tych rozwiazan i Was za odpowiedzi na moje pytanie.Dzieki > > Pozdrawiam Lucek > Jeszcze jedno wyjaśnienie,. w bazie nie zachodzi żadne sortowanie, to wynik zapytania jest sortowany i wycinasz z niego tyle rekordów ile potrzeba. Tablice w bazie są takie jak były.
--
Łukasz - 07-08-2006 01:52
Użytkownik "Artur Gancarz" <einstein@agh.edu.pl> napisał w wiadomości news:eb02tk$nug$1@news.agh.edu.pl... > > 2) jeśli chcesz np. otrzymać na podstawie poprzedniego zapytania rekordy > np. od 21 do 30 (dokładnie 10 szt.) to trzeba na końcu dopisać: > select * from tabela order by nazwa_kolumny_sortowanej limit 20,10; > > Oznacza to mniej więcej to, że ma pominąć 20 szt. z początku, a > następnie wyświetlić 10 następnych (tutaj: od 21 do 30) > i tak dalej: > select * from tabela order by nazwa_kolumny_sortowanej limit 0,10; > wyświetli rekordy od 1 do 10 (pominie ZERO) > > select * from tabela order by nazwa_kolumny_sortowanej limit 120,10; > wyświetli rekordy od 121 do 130 >
Witam,
Dołączę się do wątku bo mam podobny problem. Chcę sortować po LAST_NAME, FIRST_NAME i dla unikalności ID.
Dla samego LAST_NAME, FIRST_NAME worzyłem zapytania w stylu WHERE (LAST_NAME>X OR (LAST_NAME=X AND FIRST_NAME>Y) oczywiscie po dodaniu ID to się odpowiednio rozbuduje. Niestety Postgres 'głupiał' i nie wykorzystywał indeksu, dlatego utworzyłem indeks na LAST_NAME||' '||FIRST_NAME i uniknąłem OR w klauzuli WHERE.
Niestety po dodaniu "ID" dla uzyskania unikalności zapytania problem znów wrócił. Nie chcę tworzyć indeksów na LAST_NAME||' '||FIRST_NAME||' '||ID bo uważam takie konstrukcje za koszmarne, poza tym wiążę w ten sposób uporządkowania z indeksami, chciałbym w związku z tym przekonstruować zapytanie.
Konstrukcja LIMIT OFFSET niestety nie wygląda na wydajną dla większych zbiorów: EXPLAIN SELECT "LAST_NAME","FIRST_NAME" FROM CONTACT WHERE "COMPANY_ID" = 48 ORDER BY "LAST_NAME"||' '||"FIRST_NAME" LIMIT 20 OFFSET 30000; ---------------------- Limit (cost=19899.24..19899.29 rows=20 width=20) -> Sort (cost=19824.24..19907.55 rows=33327 width=20) Sort Key: ((("LAST_NAME")::text || ' '::text) || ("FIRST_NAME")::text) -> Bitmap Heap Scan on contact (cost=209.64..16846.87 rows=33327 widt h=20) Recheck Cond: ("COMPANY_ID" = 48) -> Bitmap Index Scan on contact_index_company (cost=0.00..209.6 4 rows=33327 width=0) Index Cond: ("COMPANY_ID" = 48) (7 rows)
W porównaniu z: EXPLAIN SELECT "LAST_NAME","FIRST_NAME" FROM CONTACT WHERE "COMPANY_ID" = 48 ORDER BY "LAST_NAME"||' '||"FIRST_NAME" LIMIT 20; ---------------------------- Limit (cost=0.00..75.27 rows=20 width=20) -> Index Scan using company_index_company_lfname on contact (cost=0.00..125 431.28 rows=33327 width=20) Index Cond: ("COMPANY_ID" = 48) (3 rows)
Dla nieunikalnego uporządkowania rozwiązanie jest proste: warunek WHERE "LAST_NAME"||' '||"FIRST_NAME">'X Y', ale po dodaniu do ORDER BY kolumny ID wszystko się wywala...
Będę bardzo wdzięczny jeśli ktoś zaproponuje jakąś konstrukcję która nie korzysta z OFFSET i umożliwia Postgresowi wykorzystanie indeksu na częśc uporządkowania
Pozdrawiam, Łukasz
zanotowane.pldoc.pisz.plpdf.pisz.pleffulla.pev.pl
|
[mysql] =?ISO-8859-2?Q?wielko=B6=E6_bazy_a_stabilno=B6=E6=2C?==?ISO-8859-2?Q?_podzia=B3_du=BFej_bazy_a_powi=B1zania_tabel?=
[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?=
[mysql] Wyszukanie =?ISO-8859-2?Q?rekord=F3w=28powiazane_tabel?==?ISO-8859-2?Q?e=29?=
[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?=
zapytanie do =?ISO-8859-2?Q?dw=F3ch_tabel_z_limitem_wier?==?ISO-8859-2?Q?szy?=
[mysql] =?ISO-8859-2?Q?po=B3=B1czenie_tabel_wg_kolumn=2C_?==?ISO-8859-2?Q?nie_wierszy?=
Zapytanie SQL z =?ISO-8859-2?Q?pust=B1_tabel=B1?=
[MySQL] Backup tabel przez "BACKUP" i problem z prawami dostępu :(
=?iso-8859-2?Q?Problem_z_left_join_-_=B3=B1czenie_kilku_tabel.?=
Jak wyswietlic dane z dwoch tabel gdy dla jednej z nich jest brak jest danej wartosci
zanotowane.pldoc.pisz.plpdf.pisz.plmisida.pev.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 |
|