Visualizando dados de Eventos Estendidos do SQL Server

16

Ultimamente, tenho explorado o uso de Eventos Estendidos no SQL Server para me ajudar a comparar e otimizar várias consultas. Até agora, para visualizar os dados do evento, eu tenho usado o recurso "Watch Live Data" no SSMS.

O problema que estou tendo é que parece que o recurso Live Events usa um buffer interno, o que significa que às vezes eu preciso executar uma consulta várias vezes para que suas informações sejam exibidas na janela. Portanto, tenho uma pergunta em duas partes:

  1. Existe uma maneira de contornar esse atraso na exibição dos eventos no feed ao vivo? (Estou fazendo isso em um banco de dados local, para que o desempenho não seja um problema)
  2. O feed ao vivo é a melhor maneira de visualizar dados de Eventos Estendidos? Existe outra ferramenta no SSMS ou não que seja melhor adaptada ao meu caso de uso?

ATUALIZAR

Conforme solicitado, aqui está a sessão:

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
fonte

Respostas:

15

Advertência : Muitas das informações fornecidas abaixo eu aprendi estritamente ao passar por dois cursos da Pluralsight de Jonathan Keyhayias . Vale a pena a despesa de um mês para a assinatura do plus passar por seus dois cursos.

Primeiro, apenas alguns pontos de interesse que acho que ajudarão (ou no máximo serão interessantes):

  • Quando uma sessão de Evento Estendido é iniciada, ela terá uma parte da memória alocada em um espaço no buffer para armazenar dados gerados pelos eventos da sessão. Na sua sessão, isso é definido como o valor padrão de 4 MB
  • Existem vários destinos disponíveis para uso. Esses destinos são synchronousou asynchronousna forma como eles recebem dados. Os dois destinos mais usados, como Target File e Ring Buffer, são assíncronos. O artigo BOL aqui indica que tipo de destino é .
  • A MAX_DISPATCH_LATENCYé uma opção de configuração que os controlos quando os dados evento é enviado para o alvo (s). O envio ocorre apenas para destinos assíncronos. Existem duas condições que farão com que os dados do evento sejam despachados: (1) o buffer de memória da sessão está cheio ou (2) os dados do evento no buffer excedem a MAX_DISPATCH_LATENCYopção configurada da sessão .
  • Quando você abre o Live Data Viewer, ele anexa um destino adicional à sessão do evento chamada "destino de streaming". Isso receberá o fluxo de eventos ao vivo conforme os buffers de memória estão sendo despachados. Na verdade, ele também altera a latência de despacho associada à sessão para 3 segundos, a fim de se aproximar da visualização em tempo real da sessão.

Agora, para pontos específicos da sua pergunta:

O problema que estou tendo é que parece que o recurso Live Events usa um buffer interno, o que significa que às vezes eu preciso executar uma consulta várias vezes para que suas informações sejam exibidas na janela. Portanto, tenho uma pergunta em duas partes a fazer

Não estou ciente de que faça isso diferente do que afirmei acima. Eu esperava que o evento fosse capturado, mas não atendeu aos limites necessários para que ele fosse despachado para o visualizador de dados ao vivo. Eu testei isso com a seguinte consulta de AdventureWorks2012:

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

Usando sua configuração de sessão de evento, com a exceção de que estou filtrando para capturar apenas dados do AdventureWorks2012banco de dados na minha instância local, posso visualizar os dados de destino para esta sessão e descobrir que a consulta foi capturada:

insira a descrição da imagem aqui insira a descrição da imagem aqui

A execução dessa consulta mais uma vez fará com que ela seja despachada e o visualizador de dados exibirá um evento. Agora, se você realmente deseja ver todos os eventos exibidos, simplesmente STOPa sessão e o buffer serão totalmente despachados. Vejo isso assim que paro minha sessão:

insira a descrição da imagem aqui

1. Existe uma maneira de contornar esse atraso na exibição dos eventos no feed ao vivo? (Estou fazendo isso em um banco de dados local, para que o desempenho não seja um problema)

Eu pensei que você poderia alterar o MAX_MEMORYvalor para um valor mais baixo, o que indicaria um pequeno tamanho de buffer para capturar eventos. No entanto, o valor mais baixo que você pode definir no SQL Server 2012 é o 200KBque a consulta que eu usei não atende a esse limite para fazer com que ele seja despachado imediatamente. A única coisa que eu pude fazer foi, no máximo, executar uma consulta que fizesse com que o buffer fosse alcançado e os eventos anteriores capturados fossem despachados:

SELECT *
FROM Person.Person
ORDER BY EmailPromotion DESC;

2.O feed ao vivo é a melhor maneira de visualizar dados de Eventos Estendidos? Existe outra ferramenta no SSMS ou não que seja melhor adaptada ao meu caso de uso?

Não que eu saiba atualmente. Eu sugeriria que o melhor método de obter dados assim que ocorresse é consultar o XML em busca do ring_bufferdestino e destruí-lo. Posso repetir o exemplo acima e, assim que executo a consulta abaixo, vejo o 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)

insira a descrição da imagem aqui

Shawn Melton
fonte
3
Ótima resposta, muito detalhada. Apenas ponto, e é mais interessante do que qualquer discussão real; você mencionou Johnathan Kehayias e, eu concordo, os cursos do Pluralsight valem 100% da taxa de 1 mês. No entanto, ele tem um blog onde fala sobre como ele odeia o alvo do buffer de anel. Foi a partir de 2014, talvez isso mudou agora, mas era uma leitura interessante: sqlskills.com/blogs/jonathan/...
Kalmino
1

O .NET 4.7.2 possui uma correção para reduzir o atraso inicial da exibição do evento ao usar o destino ativo.

David Shiflet
fonte
2
Você poderia fornecer uma referência para apoiar sua resposta? Atualmente, sua resposta não tem muito o que responder.
John aka hot2use