Zusätzlich zu Craigs gründlicher Antwort wollte ich hinzufügen, dass auf dem Cover des Buches, auf das Sie verweisen, steht:
Deckt Oracle, DB2 und SQL Server ab
Daher würde ich nicht darauf vertrauen, dass es eine gute Quelle für Ratschläge insbesondere zu PostgreSQL ist. Jedes RDBMS kann überraschend anders sein!
Ich bin ein wenig verwirrt über Ihre ursprüngliche Frage, aber hier ist ein Beispiel, das zeigt, dass der Abschnitt des Buches nicht 100% korrekt ist. Um weitere Verwirrung zu vermeiden, finden Sie hier den gesamten relevanten Absatz in der Google Buchsuche .
Die Datenbank geht davon aus, dass Indexed_Col IS NOT NULL einen zu großen Bereich abdeckt, um nützlich zu sein, sodass die Datenbank unter dieser Bedingung nicht zu einem Index fährt. In seltenen Fällen ist ein Nicht-Null-Wert so selten, dass ein Indexbereichsscan über alle möglichen Nicht-Null-Werte von Vorteil ist. Wenn Sie in solchen Fällen eine sichere Unter- oder Obergrenze für den Bereich aller möglichen Werte ermitteln können, können Sie einen Bereichsscan mit einer Bedingung wie Positive_ID_Column> -1 oder Date_Column> TO_DATE ('0001/01/01' aktivieren). , 'JJJJ / MM / TT').
Postgres kann tatsächlich (im folgenden erfundenen Fall) einen Index verwenden, um IS NOT NULL
Abfragen zu erfüllen, ohne Range-Scan-Kludges wie die vorgeschlagenen hinzuzufügen Positive_ID_Column > -1
. In den Kommentaren zu Craigs Fragen, warum Postgres diesen Index in diesem speziellen Fall auswählt, und im Hinweis zur Verwendung von Teilindizes.
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)
Dies ist übrigens Postgres 9.3, aber ich glaube, dass die Ergebnisse unter 9.1 ungefähr ähnlich wären, obwohl kein "Nur-Index-Scan" verwendet würde.
Bearbeiten: Ich sehe, Sie haben Ihre ursprüngliche Frage geklärt, und Sie fragen sich anscheinend, warum Postgres in einem einfachen Beispiel keinen Index verwendet, wie:
CREATE TABLE my_table(
a varchar NOT NULL
);
CREATE INDEX ix_my_table ON my_table(a);
SELECT a from my_table;
Wahrscheinlich, weil Sie keine Zeilen in der Tabelle haben. Fügen Sie also einige Testdaten hinzu und ANALYZE my_table;
.