Tente um índice de várias colunas, mas com a ordem inversa na segunda coluna:
CREATE INDEX index_ips_begin_end_ip_num ON ips (begin_ip_num, end_ip_num DESC);
A ordenação é principalmente irrelevante para um índice de coluna única, pois pode ser escaneado para trás quase com a mesma rapidez. Mas é importante para índices de várias colunas.
Com o índice que proponho, o Postgres pode escanear a primeira coluna e encontrar o endereço, onde o restante do índice atende à primeira condição. Em seguida, ele pode, para cada valor da primeira coluna, retornar todas as linhas que atendem à segunda condição, até que a primeira falhe. Em seguida, pule para o próximo valor da primeira coluna etc.
Isso ainda não é muito eficiente e o Postgres pode ser mais rápido apenas varrendo a primeira coluna de índice e filtrando a segunda. Depende muito da sua distribuição de dados.
De qualquer forma,
CLUSTER
usando o índice de várias colunas acima pode ajudar o desempenho:CLUSTER ips USING index_ips_begin_end_ip_num
Dessa forma, os candidatos que atendem à sua primeira condição são empacotados nas mesmas páginas de dados ou nas páginas adjacentes. Pode ajudar muito o desempenho se você tiver muitas linhas por valor da primeira coluna. Caso contrário, dificilmente é eficaz.
(Existem também ferramentas externas não bloqueadoras para esse fim:pg_repack ou pg_squeeze.)
Além disso, o autovacuum está sendo executado e configurado corretamente ou você executou
ANALYZE
na mesa? Você precisa de estatísticas atuais para o Postgres escolher os planos de consulta apropriados. O que realmente ajudaria aqui é um índice GiST para um
int8range
coluna, disponível desde o PostgreSQL 9.2. Leitura adicional:
- Otimização de consultas em um intervalo de carimbos de data/hora (duas colunas)
Se seus intervalos de IP podem ser cobertos com um dos tipos de rede integrados
inet
ou cidr
, considere substituir seus dois bigint
colunas. Ou, melhor ainda, veja o módulo adicional ip4r por Andrew Gierth (não na distribuição padrão. A estratégia de indexação muda de acordo. Tirando isso, você pode conferir esta resposta relacionada no dba.SE usando um regime sofisticado com índices parciais. Material avançado, mas oferece ótimo desempenho:
- O índice espacial pode ajudar uma consulta "intervalo - ordem por - limite"