Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> 2-kolumnowy klucz główny i prosty select, Nie korzysta z klucza?
phpion
post
Post #1





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Witam,
mam tabelę z kolumnami:
ip_from, ip_to, country_code
kolumny ip_from oraz ip_to (obie bigint) tworzą klucz główny (w takiej kolejności). Wykonanie zapytania:
  1. SELECT country_code FROM geolocalization WHERE ip_from<=3259185434 AND ip_to>=3259185434 LIMIT 1 ;

nie powoduje użycia indeksu :| tabela przeglądana jest sekwencyjnie. Czy tak powinno być? Nie powinien przypadkiem zostać użyty klucz główny?
Prosiłbym o informacje.
Pozdrawia,
pion

Ten post edytował phpion 4.12.2008, 22:19:56
Go to the top of the page
+Quote Post
Sedziwoj
post
Post #2





Grupa: Zarejestrowani
Postów: 793
Pomógł: 32
Dołączył: 23.11.2006
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Proste pytanie, ile masz tam danych?


--------------------
Algorytmy w PHP, czy ktoś o tym słyszał?
Dlaczego tak mało kobiet programuje? ponieważ nie zajmują się głupotami.
Go to the top of the page
+Quote Post
phpion
post
Post #3





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Niecałe 80 000 (dokładnie 79 011 rekordów). Chyba przy takiej liczbie powinien być wykorzystany index...
Go to the top of the page
+Quote Post
prond
post
Post #4





Grupa: Zarejestrowani
Postów: 254
Pomógł: 10
Dołączył: 8.11.2006
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Zależy jaki to rodzaj indexu. Hash jest wykorzystywany wyłącznie w warunkach równościowych, a Ty stosujesz operatory <= i >=.
Dlatego zmień index na B-tree.
Więcej znajdziesz tutaj http://www.postgresql.org/docs/8.1/static/indexes-types.html

Ten post edytował prond 11.12.2008, 09:42:52


--------------------
--------------------------------------------------------------------------------
weblog.axent.pl
--------------------------------------------------------------------------------
Go to the top of the page
+Quote Post
phpion
post
Post #5





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Dzięki za linka. Niestety utworzenie indeksu ("zwykły" lub z określeniem jako "btree") również nie powoduje jego użycia :| Ogólnie rzecz biorąc sądziłem, że nie będzie trzeba tworzyć indeksu, że zostanie użyty klucz główny. Ciągle tabela przeszukiwana jest sekwencyjnie z użyciem filtra:
Cytat
"Limit (cost=0.00..0.09 rows=1 width=3)"
" -> Seq Scan on geolocalization (cost=0.00..1689.17 rows=19742 width=3)"
" Filter: ((ip_from <= 3259185434::bigint) AND (ip_to >= 3259185434::bigint))"

Jakieś pomysły? Dodam, że samo wyszukiwanie trwa chwilę (od 16 do 47ms).
Go to the top of the page
+Quote Post
michalg
post
Post #6





Grupa: Zarejestrowani
Postów: 122
Pomógł: 8
Dołączył: 20.10.2008

Ostrzeżenie: (0%)
-----


Cytat(phpion @ 11.12.2008, 17:23:20 ) *
Dzięki za linka. Niestety utworzenie indeksu ("zwykły" lub z określeniem jako "btree") również nie powoduje jego użycia :|


Po utworzeniu indeksu nie zaszkodzi jeszcze użycie polecenia: ANALYZE geolocalization;

Próbowałeś utworzyć dwa indeksy jednokolumnowe?

Możesz ewentualnie spróbować wyłączyć skanowanie:
SET enable_seqscan=false;
EXPLAIN ANALYZE ....

Być może wtedy planner zamiast skanowania użyje indeksu. Tylko nie zdziw się, jeżeli okaże się, że czas wykonywanie się wydłuży - po prostu nie zawsze warto korzystać z indeksów - w takich sytuacjach planner wybiera inne rozwiązania - np skanowanie.
Go to the top of the page
+Quote Post
nevt
post
Post #7





Grupa: Przyjaciele php.pl
Postów: 1 595
Pomógł: 282
Dołączył: 24.09.2007
Skąd: Reda, Pomorskie.

Ostrzeżenie: (0%)
-----


spróbuj założyć indywidualne indeksy na obu kolumnach ip_ i wypróbuj zapytanie:
  1. SELECT country_code FROM (SELECT country_code, ip_to FROM geolocalization WHERE ip_from<=3259185434) AS tmp WHERE ip_to>=3259185434 LIMIT 1

u mnie na tabeli testowej ok 100k rekordów wersja z podzapytaniem i pojedynczymi indeksami jest o 30% szybsza niż wersja z AND i dwupolowym indeksem...


--------------------

-
Oh no, my young coder. You will find that it is you who are mistaken, about a great many things... -
Go to the top of the page
+Quote Post
michalg
post
Post #8





Grupa: Zarejestrowani
Postów: 122
Pomógł: 8
Dołączył: 20.10.2008

Ostrzeżenie: (0%)
-----


Cytat(nevt @ 11.12.2008, 19:26:35 ) *
u mnie na tabeli testowej ok 100k rekordów wersja z podzapytaniem i pojedynczymi indeksami jest o 30% szybsza niż wersja z AND i dwupolowym indeksem...


A bez podzapytania ale na pojedynczych indeksach? Używa wtedy indeksu?
Go to the top of the page
+Quote Post
phpion
post
Post #9





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Dzięki serdeczne wszystkim za odpowiedzi. Pomysł z podzapytaniem nie zmienił nic - uzyskiwane czasy były bardzo podobne. Jeśli natomiast chodzi o utworzenie dwóch osobnych indeksów (w sumie chciałem tego uniknąć) to zapytanie wykonuje się wręcz dłużej :|. Zostawie na razie tak jak jest. Zobaczymy czy w przyszłości nie wyjdą jakieś niespodzianki.
Jeszcze raz dzięki za zainteresowanie.
pion
Go to the top of the page
+Quote Post
nevt
post
Post #10





Grupa: Przyjaciele php.pl
Postów: 1 595
Pomógł: 282
Dołączył: 24.09.2007
Skąd: Reda, Pomorskie.

Ostrzeżenie: (0%)
-----


ale na pewno sprawdziłeś wariant który opisałem, czyli podzapytanie z oddzielnymi indeksami? bo z treści twojego postu wynika raczej, że testowałeś podzapytanie na dwupolowym indeksie, a pojedyncze indeksy tylko z wersją warunkiem AND ...


--------------------

-
Oh no, my young coder. You will find that it is you who are mistaken, about a great many things... -
Go to the top of the page
+Quote Post
phpion
post
Post #11





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Teraz sprawdziłem jeszcze raz dodając oba indeksy (jako osobne). Pokazywany czas wykonania zapytania jest mniej więcej taki sam ale w EXPLAINie widzę, że używany jest indeks założony na kolumnie ip_from. Nie wiem tylko czy go pozostawić czy nie. Teoretycznie czasy są takie same więc indeks wydaje się zbędny; z drugiej strony jednak patrząc nie powinien zaszkodzić bo na tabeli nie będą wykonywane żadne inne operacje poza SELECTami. Nie bardzo wiem co będzie lepszym wyjściem.
Go to the top of the page
+Quote Post
michalg
post
Post #12





Grupa: Zarejestrowani
Postów: 122
Pomógł: 8
Dołączył: 20.10.2008

Ostrzeżenie: (0%)
-----


Jeżeli nie musisz oszczędzać każdego bajta miejsca na bazę danych, to myślę że spokojnie możesz zostawić indeks. Być może przy select'ie różnice czsowe są niewielkie, ale indeks może się przydać przy innych selectach z tej tabeli, albo łączących się z tą tabelą.
Go to the top of the page
+Quote Post
phpion
post
Post #13





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Cytat(michalg @ 11.12.2008, 22:18:37 ) *
Być może przy select'ie różnice czsowe są niewielkie, ale indeks może się przydać przy innych selectach z tej tabeli, albo łączących się z tą tabelą.

No właśnie ta tabela będzie przeszukiwania tylko i wyłącznie tym zapytaniem, które podałem w 1 poście. To będzie w zasadzie jedyne zapytanie do niej kierowane smile.gif hehe.
Go to the top of the page
+Quote Post
nevt
post
Post #14





Grupa: Przyjaciele php.pl
Postów: 1 595
Pomógł: 282
Dołączył: 24.09.2007
Skąd: Reda, Pomorskie.

Ostrzeżenie: (0%)
-----


heh, proste wyjaśnienie... nie używa indeksu ip_from , bo wynik podzapytania nie ma już takiego indeksu... przyznaję - to mój błąd w rozumowaniu...


--------------------

-
Oh no, my young coder. You will find that it is you who are mistaken, about a great many things... -
Go to the top of the page
+Quote Post
michalg
post
Post #15





Grupa: Zarejestrowani
Postów: 122
Pomógł: 8
Dołączył: 20.10.2008

Ostrzeżenie: (0%)
-----


A tak z innej beczki - jak to IP w bazie jest zapisywane? Jako integer?

Pytam, bo zastanawiam się, czy jakikolwiek wpływ na wyszukiwanie miało by użycie w postgresie typu dla adresów internetowych. Chociaż podejrzewam, że żadnego albo minimalny.
Go to the top of the page
+Quote Post
phpion
post
Post #16





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Cytat(michalg @ 11.12.2008, 22:43:09 ) *
A tak z innej beczki - jak to IP w bazie jest zapisywane? Jako integer?

Tak, dokładniej to jako BIGINT. Myślałem nad zastosowaniem typu INET ale jednak wolałem zostać przy BIGINT w celu łatwego wykorzystania bazy w MySQL. Poza tym chyba wyszukiwanie po adresach IP byłoby wolniejsze niż po zwyklych liczbach.

Ten post edytował phpion 11.12.2008, 20:46:20
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 21.08.2025 - 16:59