Wie indiziere ich für Ungleichheitsabfragen?

10

Ich habe eine Abfrage, die Daten ausschließt, die auf dem Wert einer Float-Spalte basieren

select * 
from My_Table
where my_Float_column != 0 and my_Float_column is not null

Ich möchte keinen Float-Typ indizieren, wenn ich ihm helfen kann. Wäre der Ausführungsplan klug genug, um einen gefilterten Index wie den folgenden (bei dem ich nur die Werte 0 und Null indiziere) zu verwenden, um die Leistung zu steigern?

CREATE NONCLUSTERED INDEX IX_My_Table_Float_Filtered
    ON My_Table (my_Float_column)
    WHERE my_Float_column = 0 or my_Float_column is null
Neil P.
quelle

Antworten:

11

Wäre der Ausführungsplan klug genug, um einen gefilterten Index wie den folgenden (bei dem ich nur die Werte 0 und Null indiziere) zu verwenden, um die Leistung zu steigern?

Nein. In SQL Server gibt es keine direkte Unterstützung für die Art der Zurückweisung einzelner Zeilen, an die Sie anscheinend denken.

Allgemeiner ausgedrückt ist der gefilterte Index für die angegebene Abfrage nicht direkt hilfreich und ohnehin keine gültige Indexfilterdefinition. Sie könnten stattdessen eine indizierte Ansicht erstellen, die diese Prädikate enthält, aber es wäre immer noch nicht hilfreich, Zeilen für die Zielabfrage zu finden. Sie können die Abfrage neu schreiben, um mithilfe der indizierten Ansicht Zeilen auszuschließen, die mit einem separaten vollständigen Scan abgerufen wurden. Es ist jedoch schwer zu erkennen, wie gut dies im Allgemeinen wäre.

Das nächste, was Sie erhalten könnten, wäre wahrscheinlich ein Scan der indizierten Ansicht, die einen Bitmap-Filter ausfüllt, wobei dieser Filter als Teil eines vollständigen Scans der Zieltabelle angewendet wird. Es kann schwierig sein, diese Abfrageplanform zuverlässig zu erhalten.

Sie könnten auch eine indizierte, persistierte, berechnete Spalte verwenden, die einen CASEAusdruck verwendet. Dies würde jedoch wiederum das Umschreiben der ursprünglichen Abfrage und den Speicher für jede Zeile in der Tabelle sowie den Index erfordern.

Aus den gegebenen Informationen geht hervor, dass Sie den Index am besten wie folgt definieren können:

CREATE NONCLUSTERED INDEX IX_dbo_My_Table__Float_Filtered
ON dbo.My_Table (my_Float_column)
WHERE 
    my_Float_column <> 0 
    AND my_Float_column IS NOT NULL;
Paul White 9
quelle