Comment un proc stocké peut-il avoir plusieurs plans d'exécution?

Je travaille avec MS SQL Server 2008 R2. J'ai une procédure stockée nommée rpt_getWeeklyScheduleData . C'est la requête que j'ai utilisée pour searchr son plan d'exécution dans une database spécifique:

select * from sys.dm_exec_cached_plans cp CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) st where OBJECT_NAME(st.objectid, st.dbid) = 'rpt_getWeeklyScheduleData' and st.dbid = DB_ID() 

La requête ci-dessus me renvoie 9 lignes. Je m'attendais à 1 rangée.

Cette procédure stockée a été modifiée plusieurs fois et je crois que SQL Server a créé un nouveau plan d'exécution à chaque fois qu'il a été modifié et exécuté. Est-ce une explication correcte? Si non, comment pouvez-vous expliquer cela?

Est-il également possible de voir quand chaque plan a été créé? Si oui alors comment?

METTRE À JOUR:

C'est la signature du proc stocké:

 CREATE procedure [dbo].[rpt_getWeeklyScheduleData] ( @a_paaipk int, @a_location_code int, @a_department_code int, @a_week_start_date varchar(12), @a_week_end_date varchar(12), @a_language_code int, @a_flag int ) as begin ... end 

Le proc stocké est long; a seulement 2 si les deux conditions pour le paramètre @a_flag.

 if @a_flag = 0 begin ... end if @a_flag = 1 begin ... end 

Selon la nature de la procédure stockée (qui n'a pas été fournie), cela est très possible pour un certain nombre de raisons (très probablement pas ci-dessous):

  1. Est-ce que le proc utilise beaucoup de if this then this select, else this select/update
  2. Le proc contient-il un SQL dynamic?
  3. Exécutez-vous le SP à partir du Web et du SSMS? Ensuite, vous exécutez probablement le SP avec différents parameters de connection.
  4. Est-ce que le proc stocké a des parameters? Parfois, une différence de parameters peut entraîner l'échec d'un plan d'exécution pour un set spécifique. Un plan différent est donc utilisé.

Je vais essayer une analogie qui pourrait aider … peut-être …


Dites que vous avez une procédure stockée pour vos achats de week-end. Vous avez généralement besoin d'épicerie, parfois un filter à air, et encore less souvent un gros package de quelque chose qui doit être remplacé 4 fois par an.

  1. L'épicerie peut s'occuper de l'épicerie et est la plus proche de votre maison (5 minutes).
  2. La cible peut manipuler le filter à air et l' épicerie, mais append 25 minutes de time de déplacement.
  3. "Grand endroit de tout" a tout ce dont vous pourriez avoir besoin, mais est une heure de route.

Donc ici, en fonction de vos parameters @needsAirFilter et @needsBigPackOfSomething pourrait grandement changer votre "plan d'exécution" de votre procédure stockée de "shopping".

Si @needsAirFilter et @needsBigPackOfSomething sont false , il n'y a aucune raison de faire le trajet de 30 minutes ou d'une heure, car tout ce dont vous avez besoin est à l'épicerie.

Un par mois, @needsAirFilter est vrai, dans ce cas, nous devons aller à Target, car le plan d'exécution de l'épicerie est insuffisant.

4 fois par an @needsBigPackOfSomething est vrai, et nous devons faire l'heure de conduire le gros package de quelque chose, tout en saisissant l'épicerie, et le filter à air depuis que nous sums là.

Bien sûr … nous pourrions faire l'heure de conduire chaque fois pour faire l'épicerie, et les autres choses en cas de besoin (imaginez un plan d'exécution unique). Mais ce n'est en aucun cas le moyen le plus efficace de le faire . Dans des cas comme celui-ci, nous avons différents plans d'exécution pour quelles informations / biens sont réellement nécessaires.

Aucune idée si cela aide … mais je me suis amusé: D

En règle générale, SQL Server génère un nouveau plan de requête en fonction des valeurs des parameters transmis (cela permet de déterminer les index, le cas échéant, qu'il utilisera) et si des index sont ajoutés, modifiés ou mis à jour (sur les tables / vues utilisées) dans le proc) afin que SQL Server puisse décider qu'il est plus efficace d'utiliser un ou plusieurs index précédemment ignorés. Le plus impliqué le SQL dans le proc sera également lancer plus de travail sur le côté SQL Server, car il tente d'optimiser la requête. Si datatables changent (soudainement, vous avez beaucoup plus de clients dans NJ et il y a une requête et un index pour les états), il peut décider d'utiliser cet index et le plan de requête est modifié.