Sind diese beiden Abfragen logisch gleichwertig?
DECLARE @DateTime DATETIME = GETDATE()
Abfrage 1
SELECT *
FROM MyTable
WHERE Datediff(DAY, LogInsertTime, @DateTime) > 7
Abfrage 2
SELECT *
FROM MyTable
WHERE LogInsertTime < @DateTime - 7
Wenn sie nicht logisch äquivalent sind, können Sie mir das logische Äquivalent der ersten Abfrage geben, damit die WHERE-Klausel einen Index effektiv verwenden kann (dh Funktionsumbruch eliminieren)?
LogInsertTime
ist?Antworten:
Ob die beiden von Ihnen geposteten Abfragen logisch gleichwertig sind, spielt keine Rolle. Sie sollten keinen von ihnen verwenden. Ich werde versuchen, Sie von ein paar Dingen wegzulenken:
LogDateTime
indiziert ist (oder jemals sein könnte).Ich mag die Kurzdatumsmathematik nicht und empfehle dagegen. Sicher, es ist schneller zu tippen, aber versuchen Sie das mit einem
DATE
Datentyp und Sie werden einen hässlichen Fehler erhalten. Viel besser, um es zu formulieren, zB:quelle
Ich würde die folgende sargeable Abfrage verwenden:
Der Grund: Ich glaube, dass das Ergebnis von @ DateTime-7 nicht dokumentiert ist. Selbst wenn es zufällig DATEADD (DAY, -7, @DateTime) entspricht, kann es in einer späteren Version nicht mehr funktionieren.
quelle
- (Subtract): Subtracts two numbers (an arithmetic subtraction operator). Can also subtract a number, in days, from a date.
. Ich stimme jedoch zu, dass die Verwendung expliziter Datumsfunktionen die resultierende Abfrage lesbarer und wartbarer macht als "arithmetische Operatormagie".Sie sind nicht gleichwertig. Datensätze, die vor 7 Tagen, aber vor der aktuellen Tageszeit erstellt wurden, werden nur in Abfrage 2 zurückgegeben:
Beim Vergleichen von Tagen mit der
DATEADD
Funktion wird der Zeitteil nicht berücksichtigt . Die Funktion gibt beim Vergleich von Sonntag und Montag unabhängig von der Uhrzeit 1 zurück.Demo:
Das logische Äquivalent der ersten Abfrage, die eine potenzielle Indexnutzung ermöglicht, besteht darin, entweder den Zeitteil von zu entfernen
@DateTime
oder die Zeit auf Folgendes festzulegen0:00:00
:Der Grund, warum die erste Abfrage keinen Index für verwenden kann,
LogInsertTime
liegt darin, dass die Spalte in einer Funktion vergraben ist. Abfrage Nr. 2 vergleicht die Spalte mit einem konstanten Wert, mit dem der Optimierer einen Index für auswählen kannLogInsertTime
.quelle