Eu tenho lido este livro que diz que
O banco de dados pressupõe que Indexed_Col NÃO É NULL cobre um intervalo muito grande para ser útil, portanto, o banco de dados não direcionará para um índice dessa condição.
Reconheço que o livro tem mais de 10 anos, mas já se mostrou bastante útil - Usando as instruções recolhidas em suas páginas, eu acelerava uma consulta por um fator de dez.
Além disso, ao executar EXPLAIN ANALYZE
uma SELECT
consulta, descobri que nenhum dos meus índices está sendo usado, mesmo quando por todos os direitos eles deveriam estar.
Assim, minha pergunta é:
Supondo que exista uma tabela que tenha uma coluna, cuja definição da coluna inclua "NOT NULL" e que exista um índice que cubra essa coluna, esse índice seria usado em uma consulta dessa tabela em que as colunas fazem parte da consulta?
Gostar:
CREATE TABLE my_table(
a varchar NOT NULL
);
CREATE INDEX ix_my_table ON my_table(a);
SELECT a from my_table;
fonte
WHERE column IS NOT NULL
pode não usar o índice porque, como diz o livro: "cobre um intervalo muito grande para ser útil". Se 90% dos valores não forem nulos, um seqscan provavelmente também será mais rápido.NOT NULL
coluna para umaIS NOT NULL
consulta, a menos que esse índice também seja útil para outras partes daWHERE
cláusula, junte filtros, etc., ou seja utilizável para uma varredura ordenada apenas de índice. Em outras palavras, ele ignorará completamente o redundanteIS NOT NULL
naNOT NULL
coluna e fará escolhas de uso do índice com base em outros detalhes. (Consulte editar, reexaminar apenas o índice).Além da resposta completa de Craig, gostaria de acrescentar que a capa do livro que você menciona diz:
Portanto, não confio que seja uma ótima fonte de conselhos sobre o PostgreSQL em particular. Cada RDBMS pode ser surpreendentemente diferente!
Estou um pouco confuso com sua pergunta original, mas aqui está um exemplo que mostra que a seção do livro não está 100% correta. Para evitar mais confusões, veja o parágrafo relevante inteiro, você pode vê-lo na Pesquisa de Livros do Google .
O Postgres pode, na verdade (no caso planejado a seguir), usar um índice para atender a
IS NOT NULL
consultas sem adicionar kludges de varredura de intervalo como o sugeridoPositive_ID_Column > -1
. Veja os comentários nas perguntas de Craig sobre por que o Postgres está escolhendo esse índice nesse caso específico e a observação sobre o uso de índices parciais.A propósito, este é o Postgres 9.3, mas acredito que os resultados seriam aproximadamente similares no 9.1, embora não use uma "Index Only Scan".
Edit: Vejo que você esclareceu sua pergunta original e, aparentemente, está se perguntando por que o Postgres não está usando um índice em um exemplo simples como:
Provavelmente porque você não possui nenhuma linha na tabela. Então adicione alguns dados de teste e
ANALYZE my_table;
.fonte
NOT NULL
, não que a consulta useIS NOT NULL
como condição de índice. Isso está nos comentários que você referenciou, mas atualizamos a pergunta para incluí-la.Você não postou sua consulta ou dados de exemplo. Mas a razão mais comum pela qual os índices não são usados tem a ver com volume.
Os índices são como uma lista telefônica que traduz uma coluna em um local de linha. Se você estiver procurando apenas algumas linhas, faz sentido procurar cada linha na lista telefônica e, em seguida, procurar a linha na tabela principal.
Mas por mais de algumas linhas, é mais barato pular a lista telefônica e iterar em todas as linhas da tabela principal. Na minha experiência, o ponto de inflexão é de cerca de 100 linhas.
fonte
CREATE INDEX ix_frank ON people(name) WHERE name ='frank'
.NOT NULL