Zkuste vícesloupcový index, ale s obráceným pořadím ve druhém sloupci:
CREATE INDEX index_ips_begin_end_ip_num ON ips (begin_ip_num, end_ip_num DESC);
U jednosloupcového indexu je řazení většinou irelevantní, protože jej lze zpětně skenovat téměř stejně rychle. Ale je to důležité pro vícesloupcové indexy.
S indexem, který navrhuji, může Postgres naskenovat první sloupec a najít adresu, kde zbytek indexu splňuje první podmínku. Pak může pro každou hodnotu prvního sloupce vrátit všechny řádky, které splňují druhou podmínku, dokud první selže. Poté přejděte na další hodnotu prvního sloupce atd.
Toto stále není příliš efektivní a Postgres může být rychlejší, stačí prohledat první sloupec indexu a filtrovat druhý. Velmi záleží na vaší distribuci dat.
V každém případě CLUSTER
pomocí vícesloupcového indexu shora může výkon nápovědy:
CLUSTER ips USING index_ips_begin_end_ip_num
Tímto způsobem jsou kandidáti splňující vaši první podmínku zabaleni na stejné nebo sousední datové stránky. Pokud máte hodně řádků na hodnotu prvního sloupce, může to hodně pomoci výkonu. Jinak je to sotva efektivní.
(Existují také neblokující externí nástroje pro tento účel:pg_repack nebo pg_squeeze.)
Je také správně spuštěno a nakonfigurováno automatické vakuování nebo jste spustili ANALYZE
na stole? Pro výběr vhodných plánů dotazů potřebujete aktuální statistiky pro Postgres.
Co by zde opravdu pomohlo, je GiST index pro int8range
sloupec, dostupný od PostgreSQL 9.2.
Další čtení:
- Optimalizace dotazů na řadu časových razítek (dva sloupce)
Pokud rozsah vašich IP adres lze pokrýt jedním z integrovaných typů sítí inet
nebo cidr
, zvažte nahrazení vašich dvou bigint
sloupců. Nebo ještě lépe, podívejte se na doplňkový modul ip4r od Andrew Gierth (není ve standardní distribuci. Strategie indexování se podle toho mění.
Kromě toho si můžete tuto související odpověď prohlédnout na dba.SE pomocí sofistikovaného režimu s dílčími indexy. Pokročilé, ale poskytuje skvělý výkon:
- Může prostorový index pomoci dotazu „rozsah – pořadí podle – limit“