Fonctions SQL Server considérées comme constantes d'exécution
ne sont évalués qu'une seule fois. GETDATE()
est une telle fonction, et DATEADD(..., constant, GETDATE())
est aussi une constante d'exécution. En laissant l'appel de fonction réel à l'intérieur de la requête, vous laissez l'optimiseur voir quelle valeur sera réellement utilisée (par opposition à un reniflement de valeur variable), puis il peut ajuster ses estimations de cardinalité en conséquence, éventuellement proposer un meilleur plan.
Lisez également ceci :Dépannage des performances médiocres des requêtes : repliement constant et évaluation de l'expression pendant l'estimation de la cardinalité .
@Martin Smith
Vous pouvez exécuter cette requête :
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;
Dans mon cas, après 22 secondes, il a atteint le cas limite et la boucle est sortie. La chose importante est que la boucle est sortie avec @cnt
zéro . On pourrait s'attendre à ce que si le getdate()
est évalué par ligne, nous obtiendrions un @cnt différent du nombre @connu correct, mais pas 0. Le fait que @cnt soit égal à zéro lorsque la boucle existe montre chaque getdate()
a été évalué une fois, puis la même valeur constante a été utilisée pour chaque filtrage de ligne WHERE (aucune correspondance). Je suis conscient qu'un exemple positif ne prouve pas un théorème, mais je pense que le cas est suffisamment concluant.