web-dev-qa-db-fra.com

Quand un plan d'exécution ne montre-t-il pas à SP_WhoisActive?

J'utilise l'excellent _ d'Adam Machanic's excellent sp_WhoIsActive Procédure Pour voir l'activité et se connecter à une table pour résoudre les problèmes de fonctionnement de longues requêtes.

Pourquoi le plan d'exécution ne montre-t-il pas tout le temps dans les résultats? La plupart du temps, le query_plan la valeur est null. Si je regarde le SQL_TEXT colonne dans les résultats, je vois la requête avec les paramètres, mais aucune valeur, comme ci-dessous:

(@P0 nvarchar(4000),@P1 nvarchar(4000))
select blah from foo where a = @P0 and b = @P1 

Comment puis-je obtenir les plans d'exécution quand ils ne s'affichent pas ici? Pourquoi ne pas afficher? Dois-je utiliser des événements de profileur ou étendu? Mettreait des valeurs nominales dans ces paramètres et exécuterait la requête avec le plan d'exécution réel incluse générer le même plan qui a été utilisé lors de la journalisation?

J'ai vérifié avec le fournisseur qu'ils utilisent Hibernate 3.5.

8
SomeGuy

Comment puis-je obtenir les plans d'exécution quand ils ne s'affichent pas ici?

Une option pourrait être de capturer le plan_handle Et puis rechercher le plan de requête par la suite pour que plan_handle Utilisation de la requête suivante:

SELECT CONVERT(XML, query_plan) from sys.dm_exec_text_query_plan(
    0x0600050059E32C0/*Truncated for brevity, replace with your full plan_handle*/,
    DEFAULT,
    DEFAULT
)

Vous pouvez capturer le plan_handle utiliser la requête dans le Reason #1 section ci-dessous ou vous pouvez faire une petite modification à sp_whoisactive Pour l'exposer dans les résultats. (Il est déjà capturé dans l'intermédiaire #sessions table utilisée dans sp_whoisactive).

Dans chacun des cas où j'ai observé un plan de requête NULL, le plan de requête était disponible peu de temps après (<1 seconde dans tous mes cas) via cette méthode.

Mettreait des valeurs nominales dans ces paramètres et exécuterait la requête avec le plan d'exécution réel incluse générer le même plan qui a été utilisé lors de la journalisation?

Cela pourrait vous donner une idée de ce que le plan pourrait ressembler, et si la propriété RetrievedFromCache propriété du plan de requête est true, vous voyez probablement le même plan utilisé.

Pourquoi les plans de requête ne sont-ils pas affichés dans SP_WhoisActive?

Il y a au moins quelques raisons possibles pour lesquelles un plan pourrait ne pas apparaître, mais je n'ai pas observé cela avec la même fréquence que vous signalez, et il sera intéressant de voir toutes les autres réponses qui remplissent les lacunes.

Raison n ° 1: SYS.DM_EXEC_REQUESTS Signifie un relevé_start_offset de -1

Premièrement, jetons un coup d'œil à une version simplifiée de la section de sp_whoisactive qui recherchent des plans de requête:

SELECT t.text,
    r.plan_handle,
    r.statement_start_offset,
    r.statement_end_offset,
    query_plan = (
        SELECT CONVERT(xml, query_plan)
        FROM sys.dm_exec_text_query_plan (
            r.plan_handle, 
            r.statement_start_offset,
            r.statement_end_offset
        )
    )
FROM sys.dm_exec_sessions s
JOIN sys.dm_exec_requests r
    ON r.session_id = s.session_id
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t
WHERE s.is_user_process = 1

Et voici un exemple de résultat de mon serveur:

enter image description here

Basé sur la Documentation , il ne semble pas que -1 est une valeur attendue pour sys.dm_exec_requests.statement_start_offset. Mais il semble apparaître quelque peu fréquemment, et le sp_whoisactive La procédure ne tente pas de gérer cette situation.

Dans mes tests, je ne suis même pas sûr s'il serait possible de le faire; même lorsque vous appelez sys.dm_exec_text_query_plan Avec les valeurs par défaut (pour trouver l'ensemble du plan, pas le plan spécifique basé sur le décalage), j'ai constaté qu'aucun plan n'était fourni quand sys.dm_exec_requests.statement_start_offset était -1.

Je pense qu'il y a la possibilité d'une situation dans laquelle la demande existe, mais le plan de plan et de déclaration actuelle ne sont pas encore disponibles. Je ne connais cependant pas l'explication complète de ce comportement. Depuis un plan_handle est disponible (au moins dans mes cas avec un plan NULL), je ne pense pas que ce soit le cas que la compilation du plan se produise toujours.

Raison n ° 2: Il a fallu plus de 5 ms pour trouver le plan de requête

La mise en œuvre complète de sp_whoisactive utilise effectivement un curseur pour rechercher chaque plan à la fois. Il y a un LOCK_TIMEOUT de 5ms Pour éviter de retarder la totalité de la procédure dans le cas où une serrure est rencontrée lors de la recherche d'un plan particulier.

--Wait up to 5 ms for the SQL text, then give up
SET LOCK_TIMEOUT 5;
WHILE @@FETCH_STATUS = 0
...

Cependant, la sortie pour sp_whoisactive devrait montrer <timeout_exceeded /> dans le query_plan champ dans ce cas. J'ai vu cela plusieurs fois, alors je pense que une valeur NULL est plus probable raison n ° 1 dans votre cas.

Raison n ° 3: Le plan de requête XML est trop complexe

Cela ne semble pas probablement dans votre cas si le texte de la requête est aussi simple que votre exemple. Cependant, on dirait que la possibilité de A NULL plan de requête être affichée en raison du XML étant trop complexe.

Cependant, de regarder sp_whoisactive, on dirait que cette affaire est traitée avec un message Could not render showplan due to XML data type limitations. et instructions pour convertir le XML brut en un fichier .sqlplan.

10
Geoff Patterson