Ich habe eine Records
Tabelle mit über 100 Spalten und sehr vielen Zeilen und einen nicht gruppierten Index für 5 Felder basierend auf meinen Zugriffspfaden:
CREATE NONCLUSTERED INDEX [IX_Records_CustomerID]
ON [dbo].[Records] (
[CustomerID] ASC, -- int
[IsInvalid] ASC, -- int
[IsProcessed] ASC, -- bit
[IsRejected] ASC, -- bit
[RecordName] ASC, -- varchar(12)
;
Die 5 Felder enthalten nicht den Primärschlüssel RecordID
, der die Spalte im Clustered-Index darstellt.
Hier ist meine schlecht funktionierende Abfrage:
SELECT * FROM Records WHERE CustomerID IN (181, 283, 505)
Der Ausführungsplan zeigt, dass er einen Clustered Index Scan durchführt. Ich verstehe, dass ich Spalten auswähle, die nicht im Index enthalten sind. In Management Studio ändere ich die Abfrage in:
SELECT CustomerID, IsInvalid, IsProcessed, IsRejected, RecordName FROM Records
WHERE CustomerID IN (181, 283, 505)
Der Ausführungsplan zeigt eine Indexsuche an, und die Ausführungszeit für Abfragen sinkt von 44 Sekunden auf 2 Sekunden. Es fehlt mir jedoch die Freiheit in der Anwendung, die *
nur durch die Spalten zu ersetzen, die ich benötige und in meinen Index aufgenommen habe.
Gibt es einen Weg um den Clustered-Index-Scan herum, wenn ich gesperrt bin SELECT *
?
quelle
IN (…)
Unterabfrage?SELECT * FROM that_view WHERE CustomerID IN (...);
?Antworten:
Wenn Sie Spalten in der Ausgabe benötigen, die nicht vom Index abgedeckt werden, muss der Optimierer eine Auswahl treffen:
Welche Art und Weise gewählt wird, hängt von einer Vielzahl von Faktoren ab, einschließlich der Enge des Index, der Anzahl der Zeilen, die mit dem Prädikat übereinstimmen usw. Sie können eine Suche mit dem
FORCESEEK
Hinweis erzwingen , aber ich vermute, dass die gleiche oder eine schlechtere Leistung erzielt wird als Der Scan, den SQL Server in Ihrem Fall ausgewählt hat.Einige Optionen:
Erstellen Sie eine Ansicht, in der nur die Spalten ausgewählt werden, die Sie benötigen:
Anschließend können Sie die App in
SELECT *
dieser Ansicht ändern . Oder Sie können noch kreativer werden und die ursprüngliche Tabelle umbenennen und den Namen dieser Ansicht in den Namen der Tabelle ändern. Offensichtlich die Veränderung brechen; mit Vorsicht fortfahren.Fügen Sie alle anderen Spalten zum Schlüssel oder zur
INCLUDE
Liste für den Index hinzu. Wenn dies fest codierte Werte sind und immer die verwendeten, können Sie einen gefilterten Index in Betracht ziehen.quelle
Wenn Sie diese anderen Felder im Index haben, wird es nur noch schlimmer, wenn Sie immer select * verwenden. Versuchen Sie, einen Index nur für CustomerID zu erstellen. Das mag helfen, hängt jedoch von verschiedenen Faktoren ab, z. B. davon, wie viele IDs in der In-Liste enthalten sind und wie viele Zeilen pro Kunden-ID in der Tabelle enthalten sind.
quelle