Además de la respuesta exhaustiva de Craig, quería agregar que la portada del libro al que hace referencia dice:
Cubre Oracle, DB2 y SQL Server
Por lo tanto, no confiaría en que sea una gran fuente de asesoramiento sobre PostgreSQL en particular. ¡Cada RDBMS puede ser sorprendentemente diferente!
Estoy un poco confundido acerca de su pregunta original, pero aquí hay un ejemplo que muestra que la sección del libro no es 100% correcta. Para evitar más confusión, aquí está todo el párrafo relevante, puede verlo en Google Book Search .
La base de datos supone que Indexed_Col IS NOT NULL cubre un rango demasiado grande para ser útil, por lo que la base de datos no se dirigirá a un índice desde esta condición. En casos raros, tener un valor no nulo es tan raro que resulta beneficioso un escaneo de rango de índice sobre todos los valores no nulos posibles. En tales casos, si puede encontrar un límite inferior o superior seguro para el rango de todos los valores posibles, puede habilitar un escaneo de rango con una condición como Positivo_Columna_ID> -1 o Fecha_Columna> TO_DATE ('0001/01/01' , 'AAAA / MM / DD').
Postgres puede en realidad (en el siguiente caso artificial) usar un índice para satisfacer IS NOT NULL
consultas sin agregar kludges de escaneo de rango como el sugerido Positive_ID_Column > -1
. Vea los comentarios sobre las preguntas de Craig sobre por qué Postgres está eligiendo este índice en este caso particular, y la nota sobre el uso de índices parciales.
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)
Por cierto, esto es Postgres 9.3, pero creo que los resultados serían más o menos similares en 9.1, aunque no usaría un "Escaneo de solo índice".
Editar: veo que ha aclarado su pregunta original, y aparentemente se pregunta por qué Postgres no está usando un índice en un ejemplo simple como:
CREATE TABLE my_table(
a varchar NOT NULL
);
CREATE INDEX ix_my_table ON my_table(a);
SELECT a from my_table;
Probablemente porque no tienes filas en la tabla. Entonces agregue algunos datos de prueba y ANALYZE my_table;
.