[PostgreSql] zauważyłem coś ciekawego w moim FTI
slawekj - 11-05-2007 12:32
[PostgreSql] zauważyłem coś ciekawego w moim FTI
Witam,
Moja baza to PostgreSql 7.4
Wiem że jest szybsze wyszukiwanie po tekstach czyli choćby tsearch, ja jednak nadal korzystam z fti z contribe i to mi wystarczy.
Pamiętacie zapewne ten select
select c.* from cds c, cds-fti f1, cds-fti f2 where f1.string = 'stills' and f2.string = 'nash' and f1.id = c.oid and f2.id = c.oid ;
i przykładowo gdy szukam tekstu "o psie ktory jezdzil koleja" to mój skrypt generuje poniższy warunek where f1.string = 'o' and f2.string = 'psie' and f3.string = 'ktory' and f4.string = 'jezdzil' and f5.string = 'koleja' czyli dokladnie w takiej kolejnosci jak jest szukane Czas szukania to okolo 2000 ms.
Jednak jak to w kazdej tabeli, poszczególne słowa występują wielokrotnie co wydłuża wyszukiwanie i odpowiednio jest to u mnie: "O" 23114 razy "ktory" 113 razy "psie" 16 razy "jezdzil" 2 razy "koleja" 2 razy
Zauważyłem jednak coś dla mnie ciekawego: Mianowicie gdy przed wygenerowaniem warunku posortowalem slowa w zaleznosci od ilosc wystepowania danego slowa w tabeli czyli: "koleja jezdzil psie ktory o" where f1.string = 'koleja' and f2.string = 'jezdzil' and f3.string = 'psie' and f4.string = 'ktory' and f5.string = 'o'
to wynik uzyskuje po okolo 4 ms.
czyli różnica miedzy 2000 ms a 4 ms Zawsze myślałem że kolejność warunków nie jest istotna. Czy byłem w błędzie?
Pozdr. Sławek
hubert depesz lubaczewski - 11-05-2007 12:32
On 2007-05-04, slawekj <slawekj@nospam.pl> wrote: > select c.* > from cds c, cds-fti f1, cds-fti f2 > where f1.string = 'stills' and > f2.string = 'nash' and > f1.id = c.oid and > f2.id = c.oid ;
nie pamiętamy. czy możesz pokazać \d cds-fti? ten c.oid to faktycznie oid czy tylko kolumna tak nazwana?
> czyli różnica miedzy 2000 ms a 4 ms > Zawsze myślałem że kolejność warunków nie jest istotna. > Czy byłem w błędzie?
zasadniczo nie byłeś. ale tutaj nakładają się warunki na joinowanie.
depesz
-- quicksil1er: "postgres is excellent, but like any DB it requires a highly paid DBA. here's my CV!" :) http://www.depesz.com/ - blog dla ciebie (i moje CV)
slawekj - 11-05-2007 12:32
> select c.* > from cds c, cds-fti f1, cds-fti f2 > where f1.string = 'stills' and > f2.string = 'nash' and > f1.id = c.oid and > f2.id = c.oid ; > nie pamiętamy. > czy możesz pokazać \d cds-fti? > ten c.oid to faktycznie oid czy tylko kolumna tak nazwana?
string | character varying(50) | id | oid | Indexes: "ifti2id" btree (id) "ifti2string" btree (string)
Natomiast c.oid to faktycznie oid
Pozdr. Sławek
hubert depesz lubaczewski - 11-05-2007 12:32
On 2007-05-04, slawekj <slawekj@nospam.pl> wrote: >> czy możesz pokazać \d cds-fti? >> ten c.oid to faktycznie oid czy tylko kolumna tak nazwana? > string | character varying(50) | > id | oid | > Indexes: > "ifti2id" btree (id) > "ifti2string" btree (string) > Natomiast c.oid to faktycznie oid
zobacz czy zamiast robić wielokrotne joiny nie będzie szybciej użyć zapytania typu: select oid from cds-fti where string in ('slowo1', 'slowo2', 'slowo3', ....) group by oid having count(*) = ___ILOSC_SLOW_W_IN()___;
depesz
-- quicksil1er: "postgres is excellent, but like any DB it requires a highly paid DBA. here's my CV!" :) http://www.depesz.com/ - blog dla ciebie (i moje CV)
slawekj - 11-05-2007 12:32
> zobacz czy zamiast robić wielokrotne joiny nie będzie szybciej użyć > zapytania typu: > select oid from cds-fti where string in ('slowo1', 'slowo2', 'slowo3', > ...) group by oid having count(*) = ___ILOSC_SLOW_W_IN()___; > depesz
niestety nie działa to szybko na moim serwerze bo około 1000 ms (na samym dole wklejam explain analyse) ale select ciekawy i dało mi to troche do myślenia. mianowicie ten select zbiera ladnie wszystko z tabeli za jednym razem z pomocą indexów i stwierdziłem że pewnej rzeczy nie przeskocze, całe opóźnienie wg mnie wynika z transportowania kilkudziesięciu tys. rekordow między pamięcią i/lub dyskiem twardym. Robiąc testy na moim serwerze wyszło że pobranie całej tabeli mającej tylko 23296 rekordów za pomocą SELECT * from xxx trwa trochę ponad 200 ms ( jeden rekord to integer i varchar(50)) natomiast dodając na końcu LIMIT 1 trwa to 0.115 ms LIMIT 10 => 0.246 ms LIMIT 100 => 1.644 ms LIMIT 1000 => 14.576 ms LIMIT 10000 => 176.669 ms Czy tzn że mam źle skonfigurowany Postgresql czy to jednak tak ma być i polepszyć da się tylko po przez zmianę na lepszy serwer?
Pozdr. Sławek
----------------------------- explain analyse select id from fti2 where string in ('koleja','jezdzil','ktory','psie','o') group by id having count(*)=5;
QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ HashAggregate (cost=19426.92..19427.35 rows=86 width=4) (actual time=834.616..846.572 rows=4 loops=1) Filter: (count(*) = 5) -> Index Scan using ifti2string, ifti2string, ifti2string, ifti2string, ifti2string on fti2 (cost=0.00..19402.47 rows=4891 width=4) (actual time=0.117..685.837 rows=23296 loops=1) Index Cond: (((string)::text = 'koleja'::text) OR ((string)::text = 'jezdzil'::text) OR ((string)::text = 'ktory'::text) OR ((string)::text = 'psie'::text) OR ((string)::text = 'o'::text)) Total runtime: 847.473 ms
hubert depesz lubaczewski - 11-05-2007 12:32
On 2007-05-05, slawekj <slawekj@nospam.pl> wrote: > Robiąc testy na moim serwerze wyszło że pobranie całej tabeli mającej tylko > 23296 rekordów za pomocą SELECT * from xxx > trwa trochę ponad 200 ms ( jeden rekord to integer i varchar(50)) > natomiast dodając na końcu > LIMIT 1 trwa to 0.115 ms > LIMIT 10 => 0.246 ms > LIMIT 100 => 1.644 ms > LIMIT 1000 => 14.576 ms > LIMIT 10000 => 176.669 ms > Czy tzn że mam źle skonfigurowany Postgresql czy to jednak tak ma być i > polepszyć da się tylko po przez zmianę > na lepszy serwer?
czas prostego select * from tabela; jest limitowany zasadniczo dyskami. czyli - jeśli uważasz, że jest to za wolno - trzeba poprawić dyski - więcej, lepsze. lub dać więcej ramu na cache dyskowy.
a tak ogólnie - przesiądź się na tsearcha. nie będziesz żałował.
depesz
-- quicksil1er: "postgres is excellent, but like any DB it requires a highly paid DBA. here's my CV!" :) http://www.depesz.com/ - blog dla ciebie (i moje CV)
zanotowane.pldoc.pisz.plpdf.pisz.pleffulla.pev.pl
|
[PostgreSQL] - jak =?ISO-8859-2?Q?zabezpieczy=E6_interesy_tw?==?ISO-8859-2?Q?=F3rcy_systemu_=3F=3F=3F?=
postgresql - int/int
postgresql Select count(*) czy raczej Select count(ID)
[PostgreSQL] jak =?ISO-8859-2?Q?pobra=E6_warto=B6=E6_zwracan?==?ISO-8859-2?Q?=B1_przez_funkcj=EA=3F?=
[postgresql] INSERT OR UPDATE - jak =?ISO-8859-2?Q?b=EAdzie_na?==?ISO-8859-2?Q?jlepiej=3F?=
[postgresql] kilka =?ISO-8859-2?Q?rekord=F3w_subquery_jako_?==?ISO-8859-2?Q?string?=
[PostgreSQL] Jak =?ISO-8859-2?Q?po=B3=B1czy=E6_funkcje_z_w?==?ISO-8859-2?Q?idokiem?=
Postgres - replikcja master-master
Dopasowanie do "najlepszego" dopasowania :) [ PostgreSQL]
Problemy z =?ISO-8859-2?Q?instalacj=B1_PostgreSQL_na_syste?==?ISO-8859-2?Q?mach_Windows?=
zanotowane.pldoc.pisz.plpdf.pisz.plshutter.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 |
|