Por que o query_hash zero para instruções EXEC?

8

Estou configurando um sistema de monitoramento para o SQL Server usando Eventos Estendidos para encontrar consultas pesadas como 'feedback de produção' para nossos desenvolvedores. Estou usando os eventos sp_statement_completede sql_statement_completed, com filtros de predicado em cpu_time, leituras lógicas, etc. Eu esperava agregar os resultados database_namee query_hashdemonstrados em vários exemplos em toda a Internet, mas nos resultados vejo que query_hashé 0 para todas as instruções usando EXEC, como na tabela abaixo (carimbo de data e hora e consulta reduzidos para facilitar a leitura).

name                       timestamp      query_hash plan_handle        statement
sql_statement_completed    2016...6414    0          050056019600764... exec Shared.dbo.SyncFirm  
sql_statement_completed    2016...9946    0          06003d00e01e730... exec spSetUserAuth @userid;  
sql_statement_completed    2016...7184    0          0600e30028c9da0... exec spSetUserAuth @userid;  
sp_statement_completed     2016...0409    9826...578 0600c00028e6aa0... SELECT obfuscated_columns FROM dbo.SomeTable
sp_statement_completed     2016...1448    8660...775 060084006d2d660... INSERT INTO dbo.SomeTable ( obfuscated_columns)  EXEC(@sql)
sql_statement_completed    2016...7752    0          0600f9006c23f03... exec spSetUserAuth @userid;  
sql_statement_completed    2016...1443    1304...641 06005a0008a9b11... select SUBQ.ontrackstatus, COUNT(SUBQ.ontrac

Todos os resultados têm um valor para plan_handlee são todos diferentes, portanto, muitos planos estão sendo gerados. Outras declarações sem query_hash(que eu já vi) incluem ALTER INDEX, CHECKPOINT, UPDATE STATISTICS, COMMIT TRANSACTION, FETCH NEXT FROM Cursor, alguns INSERTs, SELECT @variable, IF (@variable = x).

Alguém sabe por que o query_hashé 0? Provavelmente estou perdendo o argumento em algum lugar sobre o SQL Query Analyzer e o EXEC, mas não consigo encontrar nenhuma pista para me indicar a direção certa. Se os resultados que estou tendo são 'normais', como agregar os resultados da melhor maneira? O agrupamento por instrução não incluiria literais, espaços em branco, etc ... que são removidos ao calcular query_hash?

EDIT: como eu vejo agora, EXEC SomeStoredProcedureinicia um procedimento armazenado (óbvio), e as instruções individuais nesse procedimento armazenado terminam na sessão de sp_statement_completedeventos como eventos, e todas elas têm um query_hash.

Portanto, para sp_statement_completed(ou seja, consultas 'reais'), eu posso agregar em query_hash e database_name e, sql_statement_completedsem query_hash (o EXEC SomeStoredProcedure), posso usar o client_connection_idpara agrupar as instruções em uma execução específica de um procedimento armazenado, para ver o que é mais parte dispendiosa do procedimento.

Bert Van Landeghem
fonte
2
Não sei por que query_hash0 é, mas por que as exec spSetUserAuth @userid;linhas têm identificadores de plano diferentes: The algorithms to match new SQL statements to existing, unused execution plans in the cache require that all object references be fully qualified.( Origem .) Se todas essas entradas fossem exec dbo.spSetUserAuth @userid;, por exemplo , você pode obter identificadores de plano idênticos para eles.
Andriy M
Eles têm plan_handles diferentes porque são usados ​​em bancos de dados diferentes, eu não percebi isso no começo. Nesse caso, as referências a objetos não são as mesmas, portanto, os diferentes planos. Obrigado por apontar.
Bert Van Landeghem
Se for esse o caso, isso não resolveria o seu problema? Você pode gerar relatórios de atividades por banco de dados e detectar problemas de detecção / parametrização de parâmetros com determinados procedimentos.
Tom V - tentativa topanswers.xyz
Bem, sim, na verdade ...
Bert Van Landeghem
3
Se o seu problema subjacente foi realmente resolvido, você poderia postar uma resposta explicando suas descobertas e como isso ajudou a resolver o problema? Você não precisa, mas, se isso puder inspirá-lo de alguma forma, isso poderá ser uma contribuição valiosa para a base de conhecimento deste site. Lembre-se de que preferimos manter os comentários por mais tempo, desde que eles ajudem a esclarecer a pergunta / resposta. Por isso, sinta-se à vontade para repetir os pontos já mencionados nesses comentários, para que possam ser removidos posteriormente com segurança.
Andriy M

Respostas:

1

Para explicar por que o hash é criado:

Quando enviamos uma consulta ao servidor, o processo de algebrizer (sim, é assim que é chamado) cria um hash, como uma assinatura codificada, da consulta. O hash é um identificador exclusivo. Um identificador é exclusivo para qualquer consulta, incluindo todo o texto que define a consulta, incluindo espaços e retornos de carro; o otimizador compara o hash às consultas no cache. Se existir uma consulta no cache que corresponda à consulta que entra no mecanismo, todo o custo do processo de otimização será ignorado e o plano de execução no cache do plano será reutilizado.

EXECinicia um procedimento armazenado que pode ter seu código alterado, uma vez que o SQL Server sabe que não precisa ser comparado EXECpara otimizá-lo, o SQL Server não cria um hash.

James Rhoat
fonte