Warum ist die Anzahl der durchgeführten Clustered-Index-Scans so hoch?

15

Ich habe zwei ähnliche Abfragen, die denselben Abfrageplan generieren, mit der Ausnahme, dass ein Abfrageplan 1316-mal einen Clustered-Index-Scan ausführt, während der andere 1-mal ausgeführt wird.

Der einzige Unterschied zwischen den beiden Abfragen besteht in unterschiedlichen Datumskriterien. Durch die Abfrage mit langer Laufzeit werden die Datumskriterien tatsächlich enger und es werden weniger Daten abgerufen.

Ich habe einige Indizes identifiziert, die bei beiden Abfragen hilfreich sind, möchte jedoch nur verstehen, warum der Operator "Clustered Index Scan" 1316-mal für eine Abfrage ausgeführt wird, die praktisch mit der identisch ist, bei der sie 1-mal ausgeführt wird.

Ich habe die Statistiken der gescannten PK überprüft und sie sind relativ aktuell.

Ursprüngliche Abfrage:

select distinct FIR_Incident.IncidentID
from FIR_Incident
left join (
    select incident_id as exported_incident_id
    from postnfirssummary
) exported_incidents on exported_incidents.exported_incident_id = fir_incident.incidentid
where FI_IncidentDate between '2011-06-01 00:00:00.000' and '2011-07-01 00:00:00.000'
    and exported_incidents.exported_incident_id is not null

Erzeugt diesen Plan: Bildbeschreibung hier eingeben

Nach dem Eingrenzen der Datumsbereichskriterien:

select distinct FIR_Incident.IncidentID
from FIR_Incident
left join (
    select incident_id as exported_incident_id
    from postnfirssummary
) exported_incidents on exported_incidents.exported_incident_id = fir_incident.incidentid
where FI_IncidentDate between '2011-07-01 00:00:00.000' and '2011-07-02 00:00:00.000'
    and exported_incidents.exported_incident_id is not null

Erzeugt diesen Plan: Bildbeschreibung hier eingeben

Seibar
quelle
Könnten Sie Ihre Abfragen in einen Codeblock anstelle von Bilddateien kopieren / einfügen?
Eric Humphrey - Lotsahelp
Sicher - Ich habe die Abfragen hinzugefügt, die jeden Plan generieren.
Seibar
In welcher Tabelle findet der Clustered-Index-Scan statt?
Eric Humphrey - Lotsahelp
Der Clustered-Index-Scan befindet sich in der Unterabfrage im linken Join (PostNFIRSSummary)
Seibar,
1
Vermutlich hat es bei der letzten Aktualisierung der Statistiken nur null oder eine Zeile gegeben, die den FI_IncidentDate between '2011-07-01 00:00:00.000' and '2011-07-02 00:00:00.000'Kriterien entsprach, und seitdem war die Anzahl der Einfügungen in diesem Bereich unverhältnismäßig hoch. Es wird geschätzt, dass für diesen Zeitraum nur 1,07 Ausführungen erforderlich sind. Nicht die 1.316, die sich in Wirklichkeit ergeben.
Martin Smith

Antworten:

9

Der JOIN nach dem Scan gibt einen Hinweis: Mit weniger Zeilen auf einer Seite des letzten Joins (natürlich von rechts nach links) wählt der Optimierer eine "verschachtelte Schleife" und keinen "Hash-Join".

Bevor ich mir das anschaue, möchte ich jedoch die Schlüsselsuche und den DISTINCT eliminieren.

  • Schlüsselsuche: Ihr Index für FIR_Incident sollte sich wahrscheinlich decken, (FI_IncidentDate, incidentid)oder umgekehrt. Oder haben Sie beide und sehen Sie, welche häufiger verwendet wird (sie können beide sein)

  • Das DISTINCTist eine Folge der LEFT JOIN ... IS NOT NULL. Das Optimierungsprogramm hat es bereits entfernt (die Pläne haben "Semi-Joins" beim finalen JOIN hinterlassen), aber ich würde EXISTS aus Gründen der Klarheit verwenden

Etwas wie:

select 
    F.IncidentID
from 
    FIR_Incident F
where 
    exists (SELECT * FROM postnfirssummary P
           WHERE P.incident_id = F.incidentid)
    AND
    F.FI_IncidentDate between '2011-07-01 00:00:00.000' and '2011-07-02 00:00:00.000'

Sie können auch Planhinweise und JOIN-Hinweise verwenden, um SQL Server dazu zu bringen, einen Hash-Join zu verwenden. Versuchen Sie jedoch, diesen zunächst normal auszuführen: Ein Leitfaden oder ein Hinweis wird den Test der Zeit wahrscheinlich nicht bestehen, da er nur für die Daten und nützlich ist Abfragen, die Sie jetzt ausführen, nicht in der Zukunft

gbn
quelle