A definição de Query_hash de sys.dm_exec_query_stats é:
query_hash: valor de hash binário calculado na consulta e usado para identificar consultas com lógica semelhante. Você pode usar o hash de consulta para determinar o uso de recursos agregados para consultas que diferem apenas por valores literais.
Mas quando procuro um query_hash específico (como mostrado abaixo), estou recebendo vários textos de consulta que diferem muito na lógica e size_in_bytes
(para o plano).
Observação: estou usando o SQL Server 2016
DECLARE @QueryHashTest BINARY(8)
SET @QueryHashTest = CONVERT(BINARY(8), 'Ð…U¹üŒv¿')
SELECT
QCP.objtype
,qStat.query_hash,
CONVERT(VARCHAR(100), qStat.query_Hash) AS VARCHAR_query_hash
,sText.text AS QueryText
,QCP.size_in_bytes
,qStat.creation_time
,qp.query_plan
FROM (
SELECT query_hash,
COUNT(query_hash) AS PlanCount
FROM sys.dm_exec_query_stats
GROUP BY query_hash
) AS MultipleQ
INNER JOIN sys.dm_exec_query_stats qStat ON MultipleQ.query_hash = qStat.query_hash
INNER JOIN sys.dm_exec_cached_plans QCP
ON QCP.plan_handle = qStat.plan_handle
CROSS APPLY sys.dm_exec_sql_text(qStat.sql_handle) AS sText
CROSS APPLY sys.dm_exec_query_plan(qStat.plan_handle) AS qp
WHERE PlanCount > 1
AND QCP.objtype = 'Proc'
AND qStat.query_hash= @QueryHashTest
AND (size_in_bytes >= 2179072 OR size_in_bytes <= 262144)
ORDER BY size_in_bytes DESC
Por que as consultas não relacionadas mostram o mesmo query_hash? É um bug ou há algo inesperado acontecendo no banco de dados?
Embora as colisões de hash sejam possíveis, suspeito que o que está acontecendo é que você está puxando o texto para todo o lote, não para a instrução específica. Um procedimento com várias instruções pode obter uma entrada de cache para cada instrução. E se algumas instruções forem idênticas nos procedimentos, elas terão o mesmo hash de consulta. Deixe-me demonstrar:
Use a consulta abaixo para ver como a mesma instrução que está em cada proc aparece separadamente.
Se você usar a consulta em sua pergunta, ela não pegará a instrução idêntica, pois ela analisa apenas o texto do lote.
Hashing significa "mapear" algo potencialmente grande para algo limitado no espaço (o query_hash). O hash de consulta é um binário(8). Então, em 8 bytes, você quer identificar algo que possa, essencialmente, ter uma infinita possibilidade de valores (a consulta). A conclusão é que você pode obter colisões - consultas diferentes resultando no mesmo hash. Isso é esperado.