Serait-il préférable que les plans de requête soient divisés par instruction de réutilisation?

11

D'après ma connaissance limitée de la façon dont les plans de requête sont compilés, stockés et récupérés par les requêtes, je comprends qu'une requête à instructions multiples ou une procédure stockée générera son plan de requête qui sera stocké dans le cache du plan de requête pour être utilisé par la requête lors d'exécutions futures.

Je pense que ce plan est récupéré du cache du plan de requête avec le hachage de requête, ce qui signifie que si la requête est modifiée et exécutée, le hachage est différent et un nouveau plan est généré car aucun hachage correspondant ne peut être trouvé dans le cache du plan de requête.

Ma question est la suivante: si un utilisateur exécute une instruction qui est l'une des instructions de la requête à instructions multiples, peut-il utiliser la partie pertinente du plan de requête déjà dans le cache pour la requête à instructions multiples? Je suppose que la réponse est non car les valeurs de hachage ne correspondront évidemment pas, mais serait-il préférable de hacher chaque instruction dans une requête multi-instructions afin qu'elles puissent être utilisées par les utilisateurs exécutant des instructions individuelles à partir de la requête?

Je pense qu'il y a des complications que je ne prends pas en compte (et ce sont celles-ci que je veux vraiment savoir), mais il semble que nous pourrions stocker le même `` plan de déclaration '' dans de nombreux plans de requête prenant plus d'espace et prenant plus CPU et temps pour générer.

Cela pourrait simplement montrer mon ignorance.

James Anderson
la source
dbidet les objectiddeux l'ont is_cache_key=1pour que vous n'obtiendrez aucune réutilisation des plans entre les différents objets compilés.
Martin Smith

Réponses:

11

Si un utilisateur exécute une instruction qui est l'une des instructions de la requête à instructions multiples, peut-il utiliser la partie pertinente du plan de requête déjà dans le cache pour la requête à instructions multiples?

Non. L'unité de base de la réutilisation du plan dans SQL Server est le lot .

Serait-il préférable de hacher chaque instruction dans une requête multi-instructions afin qu'elles puissent être utilisées par les utilisateurs exécutant des instructions individuelles à partir de la requête?

Un système réglé pour des niveaux élevés de réutilisation de plan placera du code commun (à une granularité appropriée) dans des objets réutilisables (par exemple des procédures, des fonctions, des déclencheurs) sur le serveur SQL. Il va également paramétrer explicitement tout code généré par l'application ou côté client. Pour une réutilisation maximale du plan, ces lots générés ne doivent différer que par les valeurs des paramètres.

Je m'attends à des complications que je ne prends pas en compte

Il semble que vous demandiez pourquoi SQL Server a été conçu pour mettre en cache et réutiliser au niveau du lot plutôt qu'au niveau de l'instruction. Je doute que quiconque en dehors des concepteurs originaux puisse répondre à cette question avec autorité. Quoi qu'il en soit, il me semble qu'un lot est une granularité naturelle à utiliser car il s'agit d'une unité de travail naturelle relativement autonome et représente un compromis raisonnable entre la complexité de la mise en œuvre et la probabilité de réutilisation du plan.

Il y a quelques choses qui font que les lots ne sont pas entièrement autonomes (par exemple, des tables temporaires locales créées et référencées à travers les limites des procédures stockées). Ces exceptions réduisent l'orthogonalité et ont été associées à des comportements inattendus et à des bogues au fil des ans.

Paul White 9
la source