2016-08-03 40 views
1

arbeite ich einige Abfragen auf die Optimierung und lief in eine Kuriosität, dass ich nicht sicher bin, wie zu erklären. Verwenden von SQL Server 2012 mit dem folgenden Code:TSQL: Statische Variablen vs. Berechnungen in where-Klauseln

DECLARE @startdate DATETIME2 = DATEADD(day,-1,GETDATE()), 
     @enddate DATETIME2 = GETDATE() 

SELECT * 
FROM table1 WITH(NOLOCK) 
WHERE somedate BETWEEN DATEADD(day,-1,GETDATE()) AND GETDATE() 
    AND somestate = 'NV' 

SELECT * 
FROM table1 WITH(NOLOCK) 
WHERE somedate BETWEEN @startdate AND @enddate 
    AND somestate = 'NV' 

Mit Blick auf dem tatsächlichen Ausführungsplan, hat die erste Auswahl ein Index suchen und einen Schlüsselsuche, wobei die zweiten einen Clustered-Index Scan hat. Da die SELECT s von einem funktionalen Zweck im Wesentlichen identisch sind, war ich nicht sicher, warum es den Unterschied in Ausführungsplänen geben würde. Mein letzter DBA hatte mir gesagt, dass das Deklarieren von Variablen mit dem Wert in WHERE Klauseln zu verwenden, war besser als in der WHERE Klausel, um die Berechnungen zu haben, aber dies scheint gegen diese Aussage anzuzeigen. Ich hoffe auf jede Klärung, was die große Diskrepanz zwischen den beiden Aussagen verursacht. Ich habe versucht, nach Antworten zu suchen, hatte aber nicht viel Glück. Wenn mir jemand in die richtige Richtung zeigen könnte, wäre ich sehr dankbar.

Vielen Dank!

+0

Set [Bad Habits zu treten - NOLOCK überall setzen] (http://blogs.sqlsentry.com/aaronbertrand/bad-habits-nolock-everywhere/) - es ist * nicht dies überall empfohlen * verwenden - ganz im Gegenteil! –

+0

ich im zweiten Fall denke, die SQL Server nicht bewusst ist, dass startdate und enddate verbunden sind, erwartet er alle Werte, so Scan er wählen (man denke abgesehen von Terminen Jahre). –

Antwort

0

Ich glaube, du etwas falsch verstanden, wenn die Verwendung von Berechnungen in der Klausel, wo schädlich angesehen wird. Die Verwendung einer Berechnung, die die Spalte enthält, die für die Indexierung verwendet werden würde, liegt vor, wenn Leistungsprobleme auftreten, da eine Indexsuche bei einer Berechnung nicht effektiv durchgeführt werden kann. In Ihrem Beispiel ist die Indexierungsspalte (Somedate) NICHT in der Berechnung und sollte daher Ihre Indizierung nicht negativ beeinflussen. Weitere Erläuterungen zu SARGs finden Sie unter Sql Server Query Performance (das Problem, auf das Sie sich bei Berechnungen in der WHERE-Klausel beziehen).

Wenn Sie den Ausführungsplan in SSMS anzeigen, würde ich empfehlen, zu prüfen, ob er irgendwelche Indizes vorschlägt, weil der zweite Plan, einen geclusterten Scan im Gegensatz zu einem Suchvorgang durchzuführen, einen besseren Index erstellen würde für Ihre Anfrage.

Schließlich, wenn Sie eine Schlüsselsuche sehen, die im Allgemeinen ein Hinweis darauf ist, dass Ihre Abfrage nicht optimiert ist (Key Lookup Showplan Operator).

Bei einer Nicht-Leistungs-Notiz empfiehlt Microsoft auch die Verwendung von> = < = im Gegensatz zu zwischen Daten, um versehentliche Überlappungen zu vermeiden, obwohl ich denke, dass dies nicht wirklich auf Ihre Situation zutrifft.

+0

Danke Anthony für die Info. Die erste Version dieser Selects hatte nicht den Status sastate als Teil der Klauseln und hatte extrem ähnliche Ergebnisse, da die Variable Version einen Clustered-Index-Scan durchführte und der mit der Berechnung nicht und keiner vorgeschlagen hatte auch Indizes im Ausführungsplan, was für mich verwirrender war, da ich keine Ahnung habe, wie die Einführung einer Variablen einen Index-Scan erzwingen würde. Und interessanterweise haben die neuen Versionen, die das Sustate enthalten, einen fehlenden Index in der Variablenversion, aber nicht in der berechneten Version. – Xiphoen