Ich habe dieses Buch gelesen, in dem das steht
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.
Ich erkenne, dass das Buch mehr als 10 Jahre alt ist, aber es hat sich bereits als sehr nützlich erwiesen. Mit Hilfe der Anweisungen auf den Seiten habe ich eine Abfrage um den Faktor zehn beschleunigt.
Außerdem habe ich beim Ausführen EXPLAIN ANALYZE
einer SELECT
Abfrage festgestellt, dass keiner meiner Indizes verwendet wird, auch wenn dies mit allen Rechten der Fall sein sollte.
Meine Frage lautet also:
Angenommen, es gibt eine Tabelle mit einer Spalte, deren Spaltendefinition "NOT NULL" enthält, und es gibt einen Index, der diese Spalte abdeckt. Würde dieser Index in einer Abfrage dieser Tabelle verwendet, in der die Spalten Teil der Abfrage sind?
Mögen:
CREATE TABLE my_table(
a varchar NOT NULL
);
CREATE INDEX ix_my_table ON my_table(a);
SELECT a from my_table;
quelle
WHERE column IS NOT NULL
möglicherweise nicht den Index, da, wie im Buch angegeben, "ein zu großer Bereich abgedeckt wird, um nützlich zu sein". Wenn 90% der Werte nicht null sind, ist ein Seqscan wahrscheinlich auch schneller.NOT NULL
Spalte für eineIS NOT NULL
Abfrage, es sei denn, dieser Index ist auch für andere Teile derWHERE
Klausel, Verknüpfungsfilter usw. nützlich oder kann für einen geordneten Nur-Index-Scan verwendet werden. Mit anderen Worten, die RedundanzIS NOT NULL
in derNOT NULL
Spalte wird vollständig ignoriert und die Indexverwendung wird anhand anderer Details ausgewählt. (Siehe Bearbeiten, nur Index-Scans).Zusätzlich zu Craigs gründlicher Antwort wollte ich hinzufügen, dass auf dem Cover des Buches, auf das Sie verweisen, steht:
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 .
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ügenPositive_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.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:
Wahrscheinlich, weil Sie keine Zeilen in der Tabelle haben. Fügen Sie also einige Testdaten hinzu und
ANALYZE my_table;
.quelle
NOT NULL
, nicht , dass die Abfrage verwendetIS NOT NULL
als Index Zustand. Dies steht in den Kommentaren, auf die Sie verwiesen haben, aber ich werde die Frage aktualisieren, um sie aufzunehmen.Sie haben Ihre Abfrage- oder Beispieldaten nicht veröffentlicht. Der häufigste Grund, warum Indizes nicht verwendet werden, hängt jedoch mit dem Volumen zusammen.
Indizes sind wie ein Telefonbuch, das eine Spalte in eine Zeilenposition übersetzt. Wenn Sie nur nach wenigen Zeilen suchen, ist es sinnvoll, jede Zeile im Telefonbuch und dann die Zeile in der Haupttabelle nachzuschlagen.
Bei mehr als ein paar Zeilen ist es jedoch billiger, das Telefonbuch zu überspringen und alle Zeilen in der Haupttabelle zu durchlaufen. Nach meiner Erfahrung liegt der Wendepunkt bei etwa 100 Zeilen.
quelle
CREATE INDEX ix_frank ON people(name) WHERE name ='frank'
.NOT NULL