postgres, explain, optymalizacja 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
Rafu - 17-03-2006 00:29 postgres, explain, optymalizacja
Witam. Zastanawiam się jak to działa w postgresie bo czegos nie kapuje. Mam zapytanie które łączy dwie tabele po poindeksowanym polach. bawie sie opcją ENABLE_SEQSCAN.
Mając SET ENABLE_SEQSCAN TO On;
gdy wykonuje EXPLAIN na zapytaniu dostaje cos takiego:
Dziwić się zaczynam kiedy ustawiam SET ENABLE_SEQSCAN TO OFF;
Sam explain wygląda tak:
QUERY PLAN Merge Join (cost=0.00..939885.57 rows=404707 width=2) Merge Cond: ("outer".id_stats_category = "inner".id_stats_category) -> Index Scan using call_stats_type_pkey on sapr_stats_category (cost=0.00..5.03 rows=14 width=4) -> Index Scan using sapr_stats_idx on sapr_stats (cost=0.00..934821.67 rows=404707 width=2)
I to jest normalne, używa indeksów koszt dużo niższy
Czyli po staremu, przeszukuje sekwencyjnie, koszt duży a zapytanie twra mniej wiecej tyle co przy sekwencyjnym czyli około 15 sekund. Co zrobić zeby jednak użył indeksów nie tylko przy wyjasnianiu ale faktycznie. Coś żle robie? Czego nie rozumiem? hm?
Użytkownik Rafu napisał: > > Dziwić się zaczynam kiedy ustawiam > SET ENABLE_SEQSCAN TO OFF; > > Sam explain wygląda tak: > > QUERY PLAN > Merge Join (cost=0.00..939885.57 rows=404707 width=2) > Merge Cond: ("outer".id_stats_category = "inner".id_stats_category) > -> Index Scan using call_stats_type_pkey on sapr_stats_category (cost=0.00..5.03 > rows=14 width=4) > -> Index Scan using sapr_stats_idx on sapr_stats (cost=0.00..934821.67 > rows=404707 width=2) > > I to jest normalne, używa indeksów koszt dużo niższy > > ale po faktycznym wykonaniu zapytania: > > Merge Join (cost=57341.89..63412.56 rows=404707 width=2) (actual > time=11437.360..16735.183 rows=404750 loops=1) > Merge Cond: ("outer".id_stats_category = "inner".id_stats_category) > -> Sort (cost=1.41..1.44 rows=14 width=4) (actual time=0.246..0.297 rows=14 loops=1) > Sort Key: sapr_stats_category.id_stats_category > -> Seq Scan on sapr_stats_category (cost=0.00..1.14 rows=14 width=4) (actual > time=0.035..0.135 rows=14 loops=1) > -> Sort (cost=57340.48..58352.25 rows=404707 width=2) (actual > time=11437.035..13243.206 rows=404750 loops=1) > Sort Key: sapr_stats.id_stats_category > -> Seq Scan on sapr_stats (cost=0.00..6839.07 rows=404707 width=2) (actual > time=0.154..3601.184 rows=404750 loops=1) > Total runtime: 17864.087 ms > > 58 rows fetched (13,31 sec) > > Czyli po staremu, przeszukuje sekwencyjnie, koszt duży a zapytanie twra mniej > wiecej tyle co przy sekwencyjnym czyli około 15 sekund. > Co zrobić zeby jednak użył indeksów nie tylko przy wyjasnianiu ale faktycznie. > Coś żle robie? Czego nie rozumiem? hm?
Czy wykonałeś oba zapytania w tym samym połączeniu? I czy napewno były to identyczne zapytania?
-- P.M.
rafu - 17-03-2006 00:29
> Czy wykonałeś oba zapytania w tym samym połączeniu? I czy napewno były to identyczne zapytania?
zapytania identyczne napewno nawet jednej spacji nie zmienie :-), czy w tym samym połaczeniu? Używam "EMS SQL Manager" i wykonuje skrypt wpisany w edytorze SQL, wydaje mi sie ze połaczenie to samo ponieważ między jednym a drugim SQLem sa zachowane ustawienia, zmienne srodowiskowe jakie ustawie dla postgresa np wspomniany SET ENABLE_SEQSCAN TO OFF.
Albo ten sam problem inaczej: (tabela na pona 400 000 rek. id_stats index typu btree)
1) SET ENABLE_SEQSCAN = on;
SELECT * FROM sapr_stats WHERE id_stats > 5838; czas wykonania około 30 sek.
2) SET ENABLE_SEQSCAN = off;
SELECT * FROM sapr_stats WHERE id_stats > 5838; czas wykonania około 30 sek.
czyli bez rożnicy szczegolnej.
to samo tylko z explain:
1) przy SET ENABLE_SEQSCAN = off;
wynik: QUERY PLAN Index Scan using call_stats_pkey on sapr_stats (cost=0.00..17203.14 rows=402761 width=16) Index Cond: (id_stats > 5838)
kozysta z indeksów (jesli dobrze rozumiem) kosz 17000
2) przy SET ENABLE_SEQSCAN = on;
QUERY PLAN Seq Scan on sapr_stats (cost=0.00..7902.41 rows=402761 width=16) Filter: (id_stats > 5838)
czyli sekwencyjnie koszt ponad 400000, czyli duuuuuuuzo wiecej niz poprzednio
a przy faktycznym wykonywaniu polecen oba czasy porównywalne około 25 sekund (po mojemu tak jakby nie uzywał indeksu.
Czego ja nie kapuje??? Skąd różnice w explain a faktycznym zapytaniu. czyzby przy explain mówił ze korzysta z indeksów a potem nie korzysta faktycznie? Tylko dlaczego?
rafu <rafal_sierekWYTNIJTO@poczta.onet.pl> wrote: > Albo ten sam problem inaczej: (tabela na pona 400 000 rek. id_stats index typu > btree)
Heh, ja w ogole przestaje rozumiec ta baze:
Na 8.1.3 takie polecenie zabija postgresa:
SELECT modele.id AS modele_id,marki.nazwa AS marki_nazwa,modele.nazwa AS modele_nazwa,count(pojazdy.id) AS pojazdy_count where przewoznicy.id=777 AND przewoznicy.id=wlasciciele.przewoznik_id AND wlasciciele.pojazd_id=pojazdy.id AND pojazdy.model_id = modele.id AND marki.id=modele.marka_id GROUP BY marki.nazwa,modele.nazwa,modele.id ORDER BY marki.nazwa,modele.nazwa;
rafu wrote: > a przy faktycznym wykonywaniu polecen oba czasy porównywalne około 25 > sekund (po mojemu tak jakby nie uzywał indeksu.
informacyjnie: robienie jakichkolwiek testow patrzac na explain i wyniki te ktore sie tam wypipsuja to pomylka. uzywa sie explain analyze. i wtedy wszystko widac.
depesz
-- *------------------------------------------------------------------* najwspanialszą rzeczą jaką dało nam nowoczesne społeczeństwo, jest niesamowita wręcz łatwość unikania kontaktów z nim
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