Przywolne zliczanie wierszy w Postgresql
Daniel Rurarz - 13-11-2006 00:46
Przywolne zliczanie wierszy w Postgresql
Witam, na kilku zrobionych przeze mnie stronkach zapisuję każde wejście jako nowy wiersz w tabelce `spy`
struktura:
CREATE TABLE spy ( id serial NOT NULL, date date, "hour" time without time zone, ip inet, "header" character varying, browser character varying, referer character varying, request character varying );
plus indeksy na `id` i `ip`
i jednocześnie chcąc wyświetlić ilość wejść z unikatowych adresów wykonuję zapytanie:
SELECT COUNT(DISTINCT ip) FROM spy;
i to właśnie zapytanie strasznie się ślimaczy (cała strona generuje się około 300ms przy 15 zapytaniach, przy czym 250ms poświęca właśnie na to zliczające ile jest różnych ip)
Kombinowałem co mogłem, zmieniałem indeksy na innego typu, usuwałem je (co ciekawe nie zmieniło to czasu wykonywania zapytania), przeindeksowywałem, przeczyszczałem tabelkę i cały czas wykonuje się tak samo długo.
Te 250ms przypada akurat na najczęściej odwiedzaną stronę, na innych zapytanie trwa krócej, proporcjonalnie do ilości rekordów w tabelce. Czas wykonywania zapytania, a więc generowania się strony rośnie
Może istnieje inny sposób na szybkie policzenie ile jest różnych ip w tabelce? W MySQL'u takie samo zapytanie chodzi o niebo szybciej i nie robi mu różnicy ilość wierszy, dlatego podejrzewam, że zrobiłem coś źle w postgresie.
Szukając rozwiązania zrobiłem tabelkę: CREATE TABLE spy_ip ( id serial NOT NULL, ip inet );
(ip oczywiście jest UNIQUE)
i zapytanie
SELECT COUNT(id) FROM spy_ip;
wykonuje się około 40ms, też za długo (to jest na prawdę kawał serwera i większość zapytań wykonuje się około 2~3ms), szczególnie, że taka struktura danych wymaga sprawdzenia przy każdym wejściu czy jest już w bazie ip odwiedzającego, co zwiększa ilość zapytań
Jarek - 13-11-2006 00:46
Użytkownik "Daniel Rurarz" <daniel@wytnij.rurarz.eu> napisał w wiadomości news:eia8a7$d8o$1@kujawiak.man.lodz.pl... > Witam, na kilku zrobionych przeze mnie stronkach zapisuję każde wejście > SELECT COUNT(DISTINCT ip) > FROM spy;
> i zapytanie > > SELECT COUNT(id) FROM spy_ip; > Cześć,
Postgres zlicza z indeksów, nie ze statystyk(tak jak np MSSQL) (co oznacza że będzie wolno).
pozdr
Jarek
Michal Jankowski - 13-11-2006 00:46
Daniel Rurarz <daniel@wytnij.rurarz.eu> writes:
> SELECT COUNT(DISTINCT ip) > FROM spy; > > i to właśnie zapytanie strasznie się ślimaczy
Count w postgresie jest wolny i już. Jeśli wiesz, o licznik czego będziesz się pytać, to możesz zliczać i zapamiętywać przy modyfikacji danych i potem odpytywać tylko o wartość jednej komórki...
MJ
qmac - 13-11-2006 00:47
Daniel Rurarz wrote: > Witam, na kilku zrobionych przeze mnie stronkach zapisuję każde wejście > jako nowy wiersz w tabelce `spy` > > struktura: > > CREATE TABLE spy ( > id serial NOT NULL, > date date, > "hour" time without time zone, > ip inet, > "header" character varying, > browser character varying, > referer character varying, > request character varying > ); > > plus indeksy na `id` i `ip` > > i jednocześnie chcąc wyświetlić ilość wejść z unikatowych adresów > wykonuję zapytanie: > > SELECT COUNT(DISTINCT ip) > FROM spy; > > i to właśnie zapytanie strasznie się ślimaczy > (cała strona generuje się około 300ms przy 15 zapytaniach, przy czym > 250ms poświęca właśnie na to zliczające ile jest różnych ip) > > Kombinowałem co mogłem, zmieniałem indeksy na innego typu, usuwałem je > (co ciekawe nie zmieniło to czasu wykonywania zapytania), > przeindeksowywałem, przeczyszczałem tabelkę i cały czas wykonuje się tak > samo długo. > > Te 250ms przypada akurat na najczęściej odwiedzaną stronę, na innych > zapytanie trwa krócej, proporcjonalnie do ilości rekordów w tabelce. > Czas wykonywania zapytania, a więc generowania się strony rośnie > > > Może istnieje inny sposób na szybkie policzenie ile jest różnych ip w > tabelce? > W MySQL'u takie samo zapytanie chodzi o niebo szybciej i nie robi mu > różnicy ilość wierszy, dlatego podejrzewam, że zrobiłem coś źle w > postgresie. > > Szukając rozwiązania zrobiłem tabelkę: > CREATE TABLE spy_ip ( > id serial NOT NULL, > ip inet > ); > > (ip oczywiście jest UNIQUE) > > i zapytanie > > SELECT COUNT(id) FROM spy_ip; > > wykonuje się około 40ms, też za długo (to jest na prawdę kawał serwera i > większość zapytań wykonuje się około 2~3ms), szczególnie, że taka > struktura danych wymaga sprawdzenia przy każdym wejściu czy jest już w > bazie ip odwiedzającego, co zwiększa ilość zapytań
generalnie rzecz biorac to operacja count w mysql jest wolna, dlatego lepiej jest utworzyc druga tabele w ktorej bedziesz przechowywal aktualna liczbe wierszy, dodaj do tego trigery na operacje insert, delete, ktore beda uaktulaniac ta tabele.
pozdrawiam
qmac
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.plshanti.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 |
|