Prova un indice multicolonna, ma con ordine invertito sulla seconda colonna:
CREATE INDEX index_ips_begin_end_ip_num ON ips (begin_ip_num, end_ip_num DESC);
L'ordinamento è per lo più irrilevante per un indice a colonna singola, poiché può essere scansionato all'indietro quasi altrettanto velocemente. Ma è importante per gli indici a più colonne.
Con l'indice che propongo, Postgres può scansionare la prima colonna e trovare l'indirizzo, dove il resto dell'indice soddisfa la prima condizione. Quindi può, per ogni valore della prima colonna, restituire tutte le righe che soddisfano la seconda condizione, fino a quando la prima non fallisce. Quindi passa al valore successivo della prima colonna, ecc.
Questo è ancora non molto efficiente e Postgres potrebbe essere più veloce semplicemente scansionando la prima colonna dell'indice e filtrando per la seconda. Molto dipende dalla distribuzione dei tuoi dati.
Ad ogni modo, CLUSTER
utilizzando l'indice multicolonna dall'alto can aiutare le prestazioni:
CLUSTER ips USING index_ips_begin_end_ip_num
In questo modo, i candidati che soddisfano la tua prima condizione vengono inseriti nelle pagine dati uguali o adiacenti. Può aiutare molto le prestazioni se hai molte righe per valore della prima colonna. Altrimenti è poco efficace.
(Ci sono anche strumenti esterni non bloccanti per lo scopo:pg_repack o pg_squeeze.)
Inoltre, l'autovacuum è in esecuzione e configurato correttamente o hai eseguito ANALYZE
sul tavolo? Hai bisogno di statistiche aggiornate per Postgres per scegliere i piani di query appropriati.
Ciò che potrebbe davvero aiutare qui è un indice GiST per un int8range
colonna, disponibile da PostgreSQL 9.2.
Ulteriori letture:
- Ottimizzazione delle query su un intervallo di timestamp (due colonne)
Se i tuoi intervalli IP possono essere coperti con uno dei tipi di rete integrati inet
o cidr
, considera di sostituire i tuoi due bigint
colonne. O, meglio ancora, guarda il modulo aggiuntivo ip4r di Andrew Gierth (non nella distribuzione standard. La strategia di indicizzazione cambia di conseguenza.
A parte ciò, puoi controllare questa risposta correlata su dba.SE utilizzando un regime sofisticato con indici parziali. Roba avanzata, ma offre grandi prestazioni:
- L'indice spaziale può aiutare una query "intervallo - ordine per - limite"