J'ai un SP avec un paramètre qui a NULL comme valeur par défaut, puis je veux faire une requête comme celle-ci:
SELECT ...
FROM ...
WHERE a.Blah = @Blah AND (a.VersionId = @VersionId OR (@VersionId IS NULL AND a.VersionId IS NULL));
Ce qui WHERE
précède vérifie à la fois une valeur non NULL et une valeur NULL pour @VersionId
.
Serait-il préférable en termes de performances d'utiliser à la place une IF
instruction et de dupliquer la requête en une qui recherche non NULL et une autre NULL comme ça? :
IF @VersionId IS NULL BEGIN
SELECT ...
FROM ...
WHERE a.Blah = @Blah AND a.VersionId IS NULL;
ELSE BEGIN
SELECT ...
FROM ...
WHERE a.Blah = @Blah AND a.VersionId = @VersionId;
END
Ou l'optimiseur de requête le rend essentiellement le même?
MISE À JOUR:
(Remarque: j'utilise SQL Server)
(Et pour autant que je sache, l'utilisation a.VersionId = @VersionId
dans les deux cas ne fonctionnera pas, n'est-ce pas?)
sql-server-2008
performance
user2173353
la source
la source
Réponses:
Ce modèle
peut être remplacé par
Cela vous permettra de faire correspondre un NULL avec un NULL et permettra au moteur d'utiliser
column
efficacement un index . Pour une excellente analyse approfondie de cette technique, je vous renvoie à l'article de blog de Paul White:Comme il y a deux arguments dans votre cas particulier, vous pouvez utiliser la même technique de correspondance avec
@Blah
- de cette façon, vous pourrez réécrire la clause WHERE entière de manière plus ou moins concise:Cela fonctionnera rapidement avec un index activé
(a.Blah, a.VersionId)
.Dans ce cas, oui. Dans toutes les versions (au moins) à partir de SQL Server 2005, l'optimiseur peut reconnaître le modèle
col = @var OR (@var IS NULL AND col IS NULL)
et le remplacer par laIS
comparaison appropriée . Cela dépend de la correspondance de réécriture interne, il peut donc y avoir des cas plus complexes où ce n'est pas toujours fiable.Dans les versions de SQL Server à partir de 2008 SP1 CU5 inclus , vous avez également la possibilité d'utiliser l' optimisation d'intégration des paramètres via
OPTION (RECOMPILE)
, où la valeur d'exécution de tout paramètre ou variable est incorporée dans la requête sous la forme d'un littéral avant la compilation.Ainsi, au moins dans une large mesure, dans ce cas, le choix est une question de style, bien que la
INTERSECT
construction soit indéniablement compacte et élégante.Les exemples suivants montrent le «même» plan d'exécution pour chaque variation (littéraux contre références de variables exclus):
la source