En plus de la réponse complète de Craig, je voulais ajouter que la couverture du livre auquel vous faites référence dit:
Couvre Oracle, DB2 et SQL Server
Je ne lui ferais donc pas confiance pour être une excellente source de conseils sur PostgreSQL en particulier. Chaque SGBDR peut être étonnamment différent!
Je suis un peu confus au sujet de votre question d'origine, mais voici un exemple montrant que la section du livre n'est pas correcte à 100%. Pour éviter toute confusion, voici l'intégralité du paragraphe pertinent, vous pouvez le voir dans Google Recherche de Livres .
La base de données suppose que Indexed_Col IS NOT NULL couvre une plage trop grande pour être utile, de sorte que la base de données ne conduira pas à un index à partir de cette condition. Dans de rares cas, avoir une valeur non nulle est si rare qu'un balayage de plage d'index sur toutes les valeurs non nulles possibles est bénéfique. Dans de tels cas, si vous pouvez déterminer une limite inférieure ou supérieure sûre pour la plage de toutes les valeurs possibles, vous pouvez activer un balayage de plage avec une condition telle que Positive_ID_Column> -1 ou Date_Column> TO_DATE ('0001/01/01' , «AAAA / MM / JJ»).
Postgres peut réellement (dans le cas artificiel suivant) utiliser un index pour satisfaire les IS NOT NULL
requêtes sans ajouter de contraintes de balayage de plage comme suggéré Positive_ID_Column > -1
. Voir les commentaires sur les questions de Craig pour savoir pourquoi Postgres choisit cet index dans ce cas particulier, et la note sur l'utilisation des index partiels.
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)
Il s'agit en fait de Postgres 9.3, mais je pense que les résultats seraient à peu près similaires sur 9.1, bien qu'il n'utilise pas de "Index Only Scan".
Edit: Je vois que vous avez clarifié votre question d'origine, et vous vous demandez apparemment pourquoi Postgres n'utilise pas d'index dans un exemple simple comme:
CREATE TABLE my_table(
a varchar NOT NULL
);
CREATE INDEX ix_my_table ON my_table(a);
SELECT a from my_table;
Probablement parce que vous n'avez aucune ligne dans le tableau. Ajoutez donc des données de test et ANALYZE my_table;
.