DB Engine Tuning Advisor Vorschlag Verbesserung

Wir haben eine Tabelle, die alle E-Mails abruft und die bereits gesendet wurden. Der Tisch enthält über 1 Million Zeilen.

Unten ist die Abfrage, um die Nachrichten zu finden, die noch gesendet werden müssen. Nach 5 Fehlern wird die Nachricht nicht mehr versucht und muss manuell behoben werden. SentDate bleibt null bis die Nachricht gesendet wird.

 SELECT TOP (15) ID, FromEmailAddress, FromEmailDisplayName, ReplyToEmailAddress, ToEmailAddresses, CCEmailAddresses, BCCEmailAddresses, [Subject], Body, AttachmentUrl FROM sysEmailMessage WHERE ErrorCount < 5 AND SentDate IS NULL ORDER BY CreatedDate 

Die Abfrage ist langsam, ich habe aufgrund fehlender Indizes angenommen. Ich habe die Abfrage an den Database Engine Tuning Advisor angeboten. Es schlägt den untenstehenden Index vor (und einige Statistiken, die ich allgemein ignoriere):

 SET ANSI_PADDING ON CREATE NONCLUSTERED INDEX [_dta_index_sysEmailMessage_7_1703677117__K14_K1_K12_5_6_7_8_9_10_11_15_17_18] ON [dbo].[sysEmailMessage] ( [SentDate] ASC, [ID] ASC, [ErrorCount] ASC ) INCLUDE ( [FromEmailAddress], [ToEmailAddresses], [CCEmailAddresses], [BCCEmailAddresses], [Subject], [Body], [AttachmentUrl], [CreatedDate], [FromEmailDisplayName], [ReplyToEmailAddress]) WITH (SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY] 

(Auf einem sidenote: Dieser Index hat eine vorgeschlagene Größe von 5.850.573 KB (?), Die neary 6 GB ist und macht keinen Sinn für mich überhaupt.)

Meine Frage ist, dass dieser vorgeschlagene Index Sinn macht? Warum zum Beispiel ist die ID Spalte enthalten, während es nicht in der Abfrage benötigt wird (soweit ich sagen kann)? Soweit mein Wissen über Indizes geht, sind sie gemeint, um eine schnelle search zu sein, um die relevante Zeile zu finden. Wenn ich den Index selbst entcasting musste, würde ich so etwas wie:

 SET ANSI_PADDING ON CREATE NONCLUSTERED INDEX [index_alternative_a] ON [dbo].[sysEmailMessage] ( [SentDate] ASC, [ErrorCount] ASC ) WITH (SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY] 

Ist der Optimierer wirklich clever oder ist mein Index effizienter und wohl besser?

Es gibt 2 verschiedene Aspekte für die Auswahl eines Index, die Felder, die Sie benötigen, um die Zeilen zu finden (= tatsächliche indexierte Felder) und die Felder, die danach benötigt werden (= enthaltene Felder). Wenn du immer Top 15 Zeilen machst, kannst du die eingeschlossenen Felder total ignorieren, weil 15 Keylookups schnell sein werden – und das Hinzufügen der ganzen E-Mail zum Index würde es riesig machen.

Für die indizierten Felder ist es ganz wichtig zu wissen, wie groß der Prozentsatz der data Ihren Kriterien entspricht.

Angenommen, fast alle deine Zeilen haben ErrorCount <5, du solltest es nicht im Index haben – aber wenn es ein seltener Fall ist, dann ist es gut zu haben.

Angenommen, SentDate ist wirklich selten NULL, dann solltest du das als die erste Spalte des Indexes haben.

Mit dem Erstellen von Index in dem Index hängt davon ab, wie viele Zeilen im Durchschnitt die aus der Tabelle mit den ErrorCount- und SentDate-Kriterien gefunden werden. Wenn es viel ist (Tausende) dann könnte es helfen, es dort zu haben, damit das neueste schnell gefunden werden kann.

Aber wie immer, einige Dinge beeinflussen die performance, so dass Sie testing sollten, wie verschiedene Optionen Ihre Umgebung beeinflussen.