Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Optimiert SQL Server die DATEADD-Berechnung in der ausgewählten Abfrage?

SQL Server-Funktionen, die als Laufzeitkonstanten werden nur einmal ausgewertet. GETDATE() ist eine solche Funktion, und DATEADD(..., constant, GETDATE()) ist auch eine Laufzeitkonstante. Indem Sie den eigentlichen Funktionsaufruf in der Abfrage belassen, lassen Sie den Optimierer sehen, welcher Wert tatsächlich verwendet wird (im Gegensatz zu einem Variablenwert-Sniff) und dann kann er seine Kardinalitätsschätzungen entsprechend anpassen und möglicherweise einen besseren Plan erstellen.

Lesen Sie auch Folgendes:Troubleshooting Poor Query Performance:Constant Folding and Expression Evaluation While Cardinality Estimation .

@Martin Smith

Sie können diese Abfrage ausführen:

set nocount on;
declare @known int;
select @known = count(*) from sysobjects;
declare @cnt int = @known;
while @cnt = @known
    select @cnt = count(*) from sysobjects where getdate()=getdate()
select @cnt, @known;

In meinem Fall traf es nach 22 Sekunden auf den Grenzfall und die Schleife wurde verlassen. Wichtig ist, dass die Schleife mit @cnt beendet wird null . Das würde man erwarten, wenn getdate() pro Zeile ausgewertet wird, dann würden wir ein @cnt erhalten, das sich von der korrekten @known-Zählung unterscheidet, aber nicht 0. Die Tatsache, dass @cnt null ist, wenn die Schleife existiert, zeigt jedes getdate() wurde einmal ausgewertet und dann wurde derselbe konstante Wert für jede Zeile WHERE-Filterung verwendet (matching none). Mir ist bewusst, dass ein positives Beispiel kein Theorem beweist, aber ich denke, der Fall ist schlüssig genug.