Visualización de datos de eventos extendidos de SQL Server

16

Últimamente he estado explorando el uso de eventos extendidos en SQL Server para ayudarme a comparar y optimizar varias consultas. Hasta ahora, para ver los datos del evento, he estado usando la función "Ver datos en vivo" en SSMS.

El problema que tengo es que parece que la función Live Events utiliza un búfer interno, lo que significa que a veces necesito ejecutar una consulta varias veces para que su información se muestre en la ventana. Por lo tanto, tengo una pregunta de dos partes para hacer:

  1. ¿Hay alguna forma de evitar este retraso para que los eventos se muestren en la transmisión en vivo? (Estoy haciendo esto en una base de datos local, por lo que el rendimiento no es un problema)
  2. ¿Es la transmisión en vivo la mejor manera de visualizar datos de eventos extendidos? ¿Hay alguna otra herramienta en SSMS o no que esté mejor adaptada a mi caso de uso?

ACTUALIZAR

Según lo solicitado, aquí está la sesión:

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
Levi Botelho
fuente

Respuestas:

15

Advertencia : Gran parte de la información proporcionada a continuación la aprendí estrictamente al pasar por dos cursos de Pluralsight de Jonathan Keyhayias . Vale la pena el gasto de un mes por la suscripción plus para completar sus dos cursos.

Primero, solo algunos puntos de interés que creo que ayudarán (o como mucho serán de interés):

  • Cuando se inicia una sesión de evento extendido, tendrá una porción de memoria asignada a un espacio de búfer para almacenar datos generados por los eventos de la sesión. En su sesión, esto se establece en el valor predeterminado de 4 MB
  • Hay múltiples objetivos disponibles para usar. Estos objetivos sonsynchronous o asynchronousen la forma en que reciben los datos. Los dos objetivos más utilizados son Target File y Ring Buffer, ambos son asíncronos. El artículo de BOL aquí indica de qué tipo es cada objetivo .
  • Esta MAX_DISPATCH_LATENCYes una opción de configuración que controla cuándo se envían los datos del evento a los objetivos. El envío solo se produce para objetivos asincrónicos. Hay dos condiciones que harán que se envíen datos de eventos: (1) el búfer de memoria para la sesión está lleno o (2) los datos de eventos en el búfer exceden la MAX_DISPATCH_LATENCYopción configurada de la sesión .
  • Cuando abra el Visor de datos en vivo, adjuntará un objetivo adicional a la sesión del evento denominado "objetivo de transmisión". Esto recibirá la transmisión del evento en vivo a medida que se despachan las memorias intermedias. En realidad, también cambiará la latencia de envío asociada con la sesión a 3 segundos para obtener una vista cercana en tiempo real de la sesión.

Ahora a puntos específicos en su pregunta:

El problema que tengo es que parece que la función Live Events utiliza un búfer interno, lo que significa que a veces necesito ejecutar una consulta varias veces para que su información se muestre en la ventana. Por lo tanto, tengo una pregunta de dos partes para hacer

No soy consciente de que hace esto aparte de lo que dije anteriormente. Esperaría que el evento se haya capturado, simplemente no ha alcanzado los umbrales requeridos para que se envíe a su visor de datos en vivo. Probé esto con la siguiente consulta de AdventureWorks2012:

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

Utilizando la configuración de sesión de evento, con la excepción de que estoy filtrando para capturar solo datos para la AdventureWorks2012base de datos en mi instancia local, puedo ver los datos de destino para esta sesión y encontrar que la consulta fue capturada:

ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí

Ejecutar esta consulta una vez más finalmente hará que se despache y el visor de datos muestre un evento. Ahora, si realmente desea ver todos los eventos que se muestran, simplemente STOPla sesión y el búfer se distribuirán por completo. Veo esto una vez que detengo mi sesión:

ingrese la descripción de la imagen aquí

1. ¿Hay alguna forma de evitar este retraso para que los eventos se muestren en la transmisión en vivo? (Estoy haciendo esto en una base de datos local, por lo que el rendimiento no es un problema)

Pensé que podría cambiarlo MAX_MEMORYa un valor más bajo que indicaría un tamaño de búfer pequeño para capturar eventos. Sin embargo, el valor más bajo en el que puede establecer esto en SQL Server 2012 es 200KBque la consulta que utilicé no cumple ese límite para que se envíe de inmediato. Lo único que pude hacer fue a lo sumo ejecutar una consulta que haría que se alcanzara el búfer y que se enviaran los eventos anteriores capturados:

SELECT *
FROM Person.Person
ORDER BY EmailPromotion DESC;

¿Es la transmisión en vivo la mejor manera de visualizar datos de eventos extendidos? ¿Hay otra herramienta en SSMS o no que esté mejor adaptada a mi caso de uso?

No es que yo sepa actualmente. Sugeriría que el mejor método para obtener datos tan pronto como ocurra es consultar el XML para el ring_bufferobjetivo y simplemente eliminarlo. Puedo repetir el ejemplo anterior y tan pronto como ejecuto la consulta a continuación veo el evento.

-- 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)

ingrese la descripción de la imagen aquí


fuente
3
Gran respuesta, muy detallada. Solo apunte, y es más interesante que cualquier discusión real; mencionaste a Johnathan Kehayias y, estoy de acuerdo, sus cursos de Pluralsight valen el 100% de la tarifa de 1 mes. Sin embargo, tiene un blog donde habla sobre cómo odia el objetivo de Ring Buffer. Era de 2014, así que tal vez eso haya cambiado ahora, pero fue una lectura interesante: sqlskills.com/blogs/jonathan/…
Kalmino el
1

.Net 4.7.2 tiene una solución para reducir el retraso inicial para la visualización de eventos cuando se usa el objetivo en vivo.

David Shiflet
fuente
2
¿Podría proporcionar una referencia para respaldar su respuesta? Actualmente su respuesta no contiene mucho para acompañar.
John aka hot2use