L'utilisation de IF dans T-SQL affaiblit ou rompt la mise en cache du plan d'exécution?

20

Il m'a été suggéré que l'utilisation d'instructions IF dans des lots t-SQL nuisait aux performances. J'essaie de trouver une confirmation ou de valider cette affirmation. J'utilise SQL Server 2005 et 2008.

L'affirmation est qu'avec le lot suivant: -

IF @parameter = 0
 BEGIN
  SELECT ... something
 END

ELSE
 BEGIN
  SELECT ... something else
 END

SQL Server ne peut pas réutiliser le plan d'exécution généré car la prochaine exécution peut nécessiter une branche différente. Cela implique que SQL Server éliminera entièrement une branche du plan d'exécution sur la base du fait que pour l'exécution en cours, il peut déjà déterminer quelle branche est nécessaire. Est-ce vraiment vrai?

De plus ce qui se passe dans ce cas: -

IF EXISTS (SELECT ....)
 BEGIN
  SELECT ... something
 END

ELSE
 BEGIN
  SELECT ... something else
 END

où il n'est pas possible de déterminer à l'avance quelle branche sera exécutée?

AnthonyWJones
la source
1
SQL Server peut et réutilise le plan d'exécution car il ne prend pas en compte les branches, uniquement les instructions contenues dans les branches.
MartinC

Réponses:

10

SQL Server optimise le processus de compilation du plan de requête pour la procédure stockée en ignorant les branches conditionnelles à l'intérieur de la procédure stockée. Le plan sera généré en fonction des paramètres utilisés pour la première exécution, cela posera des problèmes si les paramètres sont différents pour les branches.

Je placerais le SQL de chacune des branches dans leur propre procédure stockée, de sorte que le plan généré soit basé sur l'utilisation réelle des paramètres de cette branche.

MartinC
la source
6

Le seul raccourci sera IF 1 = 1

@Parameter et EXISTS nécessitent toujours un traitement pour le "cas général" (par @parameter = 42exemple)

En disant que ... que dit le plan d'exécution réel ainsi que le profileur capturant les événements de recomplition? (Je n'aime pas les plans estimés selon la réponse de Jao)

gbn
la source
3

Essayez d'afficher le plan d'exécution estimé, pas le réel. Vous verrez que le premier contient l' CONDopérateur.

Cet opérateur a également été inclus dans le plan d'exécution mis en cache. Dans votre exemple, le plan d'excution estimé contiendra un opérateur COND et 2 branches SELECT et sera donc entièrement réutilisable. Parce que lors de l'exécution d'un lot, SQL Server évalue non seulement les instructions DML mais aussi toutes les autres, en les obtenant du plan.

Le plan d'exécution interne est une structure similaire à l'arborescence des expressions.

Tom V - Équipe Monica
la source
0

Les plans seront créés en fonction des paramètres transmis, donc en réalité, je dirais que non - une logique conditionnelle qui est normalement basée sur des paramètres ne nuit pas aux performances.

Vous obtiendrez plusieurs plans produits, en supposant que les paramètres provoquent suffisamment de variance pour que l'optimiseur de requête le remarque.

Vous pouvez voir lequel en activant le plan Show Execution, en exécutant les scripts - notez les différences dans le plan. Lorsque vous exécutez les procédures (je suppose que les procédures stockées ici), vous remarquerez que la première fois est généralement plus rapide, le deuxième hit utilise le plan stocké. Modifiez les paramètres et répétez puis exécutez les paramètres d'origine - en théorie, le plan sera toujours dans le cache, mais cela dépend de l'utilisation du serveur (ticks de cache - ils ne restent pas éternellement ..) etc.

Barry King
la source
0

Peut-être que cela a été amélioré en 2005 et 2008, mais l'utilisation de conditions en 2000 serait probablement pire que ce que vous décrivez, il compilerait un plan pour gérer au mieux la première exécution de la procédure, puis utiliserait ce plan pour exécuter la procédure même lorsque les conditions modifié. D'après mon expérience, cela a provoqué des requêtes qui s'exécutaient en quelques minutes pour s'exécuter en quelques heures. Bien que j'utilise 2008 maintenant et que j'utilise 2005, je ne peux pas commenter le fonctionnement des coditions là-bas puisque je ne les utilise plus.


la source
2
2005+ a une recompilation au niveau des instructions pour que vous n'ayez plus "un seul plan par session" tout le temps
gbn