Visualisation des données d'événements étendus SQL Server


16

Dernièrement, j'ai exploré l'utilisation des événements étendus dans SQL Server pour m'aider à comparer et à optimiser diverses requêtes. Jusqu'à présent, pour afficher les données d'événement, j'utilisais la fonction "Watch Live Data" dans SSMS.

Le problème que j'ai est qu'il semble que la fonctionnalité Live Events utilise un tampon interne, ce qui signifie que parfois je dois exécuter une requête plusieurs fois pour obtenir ses informations à afficher dans la fenêtre. J'ai donc une question en deux parties à poser:

  1. Existe-t-il un moyen de contourner ce délai pour afficher les événements dans le flux en direct? (Je fais cela sur une base de données locale, donc les performances ne sont pas un problème)
  2. Le flux en direct est-il le meilleur moyen de visualiser les données d'événements étendus? Existe-t-il un autre outil dans SSMS ou non mieux adapté à mon cas d'utilisation?

MISE À JOUR

Comme demandé, voici la session:

CREATE EVENT SESSION [Simple Query Benchmarking] ON SERVER 
ADD EVENT sqlserver.sql_batch_completed(SET collect_batch_text=(1)
    ACTION(sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.sql_text)
    WHERE ([package0].[equal_boolean]([sqlserver].[is_system],(0)) AND [package0].[greater_than_uint64]([duration],(1000)))) 
ADD TARGET package0.ring_buffer
WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=1 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=ON,STARTUP_STATE=OFF)
GO

Réponses:


15

Caveat : Une grande partie des informations fournies ci - dessous j'ai appris strictement de passer par deux cours Pluralsight par Jonathan Keyhayias . Il vaut bien la dépense d'un mois pour l'abonnement plus pour suivre ses deux cours.

Tout d'abord, quelques points d'intérêt qui, je pense, seront utiles (ou tout au plus intéressants):

  • Lorsqu'une session d'événement étendu est démarrée, une partie de la mémoire est allouée à un espace tampon pour stocker les données générées par les événements de la session. Dans votre session, ce paramètre est défini sur la valeur par défaut de 4 Mo
  • Il existe plusieurs cibles disponibles à utiliser. Ces cibles sont soit synchronousou asynchronousdans la façon dont ils reçoivent les données. Les deux cibles les plus couramment utilisées étant le fichier cible et le tampon en anneau sont toutes deux asynchrones. L'article BOL ici indique de quel type est chaque cible .
  • Il MAX_DISPATCH_LATENCYs'agit d'une option de configuration qui contrôle le moment où les données d'événement sont envoyées aux cibles. La répartition ne se produit que pour les cibles asynchrones. Il y a deux conditions qui entraîneront la distribution des données d'événement: (1) le tampon de mémoire pour la session est plein ou (2) les données d'événement dans le tampon dépassent l' MAX_DISPATCH_LATENCYoption configurée de la session .
  • Lorsque vous ouvrez la visionneuse de données en direct, elle associera une cible supplémentaire à la session d'événement appelée «cible de streaming». Celui-ci recevra le flux d'événements en direct lors de l'envoi de tampons de mémoire. En fait, cela changera également la latence de répartition associée à la session à 3 secondes afin d'obtenir une vue en temps quasi réel de la session.

Passons maintenant à des points spécifiques de votre question:

Le problème que j'ai est qu'il semble que la fonctionnalité Live Events utilise un tampon interne, ce qui signifie que parfois je dois exécuter une requête plusieurs fois pour obtenir ses informations à afficher dans la fenêtre. J'ai donc une question en deux parties à poser

Je ne suis pas conscient qu'il fait cela autre que ce que j'ai déclaré ci-dessus. Je suppose que l'événement a été capturé, il n'a tout simplement pas atteint les seuils requis pour qu'il soit envoyé à votre visionneuse de données en direct. J'ai testé cela avec la requête suivante de AdventureWorks2012:

SELECT * FROM dbo.ErrorLog
WAITFOR DELAY '00:00:01' ;
GO

En utilisant la configuration de votre session d'événement, à l'exception que je filtre pour capturer uniquement les données de la AdventureWorks2012base de données sur mon instance locale, je peux afficher les données cibles pour cette session et trouver que la requête a été capturée:

entrez la description de l'image ici entrez la description de l'image ici

L'exécution de cette requête une fois de plus entraînera finalement son envoi et le visualiseur de données affiche un événement. Maintenant, si vous voulez réellement voir tous les événements qui sont affichés simplement STOPla session et le tampon seront entièrement distribués. Je vois cela une fois que j'arrête ma session:

entrez la description de l'image ici

1.Y a-t-il un moyen de contourner ce délai pour afficher les événements dans le flux en direct? (Je fais cela sur une base de données locale, donc les performances ne sont pas un problème)

J'avais pensé que vous pouviez changer la MAX_MEMORYpour une valeur inférieure qui indiquerait une petite taille de tampon pour capturer les événements. Cependant, la valeur la plus basse que vous pouvez définir dans SQL Server 2012 est celle à 200KBlaquelle la requête que j'ai utilisée ne respecte pas cette limite pour qu'elle soit immédiatement envoyée. La seule chose que je pouvais faire était tout au plus d'exécuter une requête qui entraînerait l'atteinte du tampon et la distribution des événements précédents capturés:

SELECT *
FROM Person.Person
ORDER BY EmailPromotion DESC;

2.Le flux en direct est-il le meilleur moyen de visualiser les données d'événements étendus? Existe-t-il un autre outil dans SSMS ou non mieux adapté à mon cas d'utilisation?

Pas que je sache actuellement. Je suggérerais que la meilleure méthode pour extraire des données dès qu'elles se produisent consiste à interroger le XML pour la ring_buffercible et à la détruire. Je peux répéter l'exemple ci-dessus et dès que j'exécute la requête ci-dessous, je vois l'événement.

-- Create XML variable to hold Target Data
DECLARE @target_data XML
SELECT  @target_data = CAST([t].[target_data] AS XML)
FROM    [sys].[dm_xe_sessions] AS s
JOIN    [sys].[dm_xe_session_targets] AS t
        ON [t].[event_session_address] = [s].[address]
WHERE   [s].[name] = N'Simple Query Benchmarking' AND
        [t].[target_name] = N'ring_buffer' ;

-- Return the full XML document
--SELECT @target_data;

--Shred XMl to get needed data
SELECT  DATEADD(hh, DATEDIFF(hh, GETUTCDATE(), CURRENT_TIMESTAMP), n.value('(@timestamp)[1]', 'datetime2')) AS [timestamp],
    n.value('(data[@name="duration"]/value)[1]', 'bigint') as duration,
    n.value('(action[@name="sql_text"]/value)[1]', 'varchar(max)') as sql_text
FROM @target_data.nodes('RingBufferTarget/event[@name=''sql_batch_completed'']') AS q(n)

entrez la description de l'image ici


3
Excellente réponse, très détaillée. Seul point, et c'est plus un intérêt que n'importe quelle vraie discussion; vous avez mentionné Johnathan Kehayias et, je suis d'accord, ses cours Pluralsight valent à 100% les frais d'un mois. Cependant, il a un blog où il explique comment il déteste la cible Ring Buffer. C'était à partir de 2014, alors peut-être que cela a changé maintenant, mais c'était une lecture intéressante: sqlskills.com/blogs/jonathan/…
Kalmino

1

.Net 4.7.2 a un correctif pour réduire le délai initial d'affichage des événements lors de l'utilisation de la cible en direct.


2
Pourriez-vous fournir une référence à l'appui de votre réponse? Actuellement, votre réponse ne contient pas grand-chose.
John aka hot2use
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.