Ces deux requêtes sont-elles logiquement équivalentes?
DECLARE @DateTime DATETIME = GETDATE()
Requête 1
SELECT *
FROM MyTable
WHERE Datediff(DAY, LogInsertTime, @DateTime) > 7
Requête 2
SELECT *
FROM MyTable
WHERE LogInsertTime < @DateTime - 7
S'ils ne sont pas logiquement équivalents, pouvez-vous me donner l'équivalent logique de la première requête afin que la clause WHERE puisse utiliser efficacement un index (c'est-à-dire éliminer le wrapping de fonction)?
LogInsertTime
est ce type ?Réponses:
Que les deux requêtes que vous avez publiées soient logiquement équivalentes n'a pas d'importance; vous ne devez utiliser aucun d'eux. Je vais essayer de vous éloigner de deux ou trois choses:
LogDateTime
est indexée (ou pourrait l'être).Je n'aime pas le calcul de la date abrégée et je le déconseille. Bien sûr, il est plus rapide de taper, mais essayez cela avec un
DATE
type de données et vous obtiendrez une erreur laide. Beaucoup mieux pour le préciser, par exemple:la source
J'utiliserais la requête discutable suivante:
La raison: je crois que le résultat de @ DateTime-7 n'est pas documenté. Même s'il s'avère justement être équivalent à DATEADD (DAY, -7, @DateTime), il peut se casser dans une version ultérieure.
la source
- (Subtract): Subtracts two numbers (an arithmetic subtraction operator). Can also subtract a number, in days, from a date.
. Néanmoins, je suis d'accord que l'utilisation de fonctions de date explicites rend la requête résultante plus lisible et maintenable que la "magie d'opérateur arithmétique".Ils ne sont pas équivalents. Les enregistrements datant de 7 jours, mais antérieurs à l' heure actuelle , ne seront renvoyés que dans la requête n ° 2:
Lors de la comparaison des jours à l'aide de la
DATEADD
fonction , elle ne prend pas en compte la partie temps . La fonction renverra 1 lors de la comparaison dimanche et lundi, quelles que soient les heures.Démo:
L'équivalent logique de la première requête qui permettra l'utilisation potentielle de l'index est de supprimer la partie temporelle de
@DateTime
ou de définir l'heure sur0:00:00
:La raison pour laquelle la première requête ne peut pas utiliser un index
LogInsertTime
est parce que la colonne est enterrée dans une fonction. La requête n ° 2 compare la colonne à une valeur constante qui permet à l'optimiseur de choisir un indexLogInsertTime
.la source