Além da resposta completa de Craig, gostaria de acrescentar que a capa do livro que você menciona diz:
Abrange Oracle, DB2 e SQL Server
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 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. Em casos raros, ter qualquer valor não nulo é tão raro que uma varredura de intervalo de índice sobre todos os possíveis valores nulos é benéfica. Nesses casos, se você descobrir um limite inferior ou superior seguro para o intervalo de todos os valores possíveis, poderá ativar uma verificação de intervalo com uma condição como Positive_ID_Column> -1 ou Date_Column> TO_DATE ('0001/01/01' , 'AAAA / MM / DD').
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 sugerido Positive_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.
CREATE TABLE bar (a int);
INSERT INTO bar (a) SELECT NULL FROM generate_series(1,1000000);
INSERT INTO bar (a) VALUES (1);
CREATE INDEX bar_idx ON bar (a);
EXPLAIN ANALYZE SELECT * FROM bar WHERE a IS NOT NULL;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------
Index Only Scan using bar_idx on bar (cost=0.42..8.44 rows=1 width=4) (actual time=0.094..0.095 rows=1 loops=1)
Index Cond: (a IS NOT NULL)
Heap Fetches: 1
Total runtime: 0.126 ms
(4 rows)
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:
CREATE TABLE my_table(
a varchar NOT NULL
);
CREATE INDEX ix_my_table ON my_table(a);
SELECT a from my_table;
Provavelmente porque você não possui nenhuma linha na tabela. Então adicione alguns dados de teste e ANALYZE my_table;
.