ATUALIZAÇÃO: Este é definitivamente um bug. Para detalhes completos, consulte este item de conexão .
Ao testar algumas alterações no sp_BlitzCache (divulgação completa, sou um dos autores), me deparei com o que achava ser um bug em nosso código.
Em um momento, estamos combinando o hash do plano de consulta para obter o custo da consulta. Fazemos isso da seguinte maneira:
statement.value('sum(/p:StmtSimple[xs:hexBinary(substring(@QueryHash, 3)) =
xs:hexBinary(sql:column("b.QueryHash"))]/@StatementSubTreeCost)', 'float')
Até onde eu vi, isso funcionou. No entanto, em um caso estranho, a substring no XML estava gerando um NULL
valor, e o plano estava mostrando um custo de 0, apesar de bastante alto.
Analisando o plano de execução (divulgação completa, trabalho para a empresa que hospeda Colar o plano), notei que o hash do plano de consulta para o hash de um problema tinha 17 caracteres, enquanto o restante tem 18 anos. Aqui estão alguns exemplos:
QueryPlanHash = "0x4410B0CA640CDA89" QueryPlanHash = "0x2262FEA4CE645569" QueryPlanHash = "0xED4F225CC0E97E5" - Problema! QueryPlanHash = "0xBF878EEE6DB955EA" QueryPlanHash = "0x263B53BC8C14A452" QueryPlanHash = "0x89F5F146CF4B476F" QueryPlanHash = "0xEF47EA40805C8961" QueryPlanHash = "0xB7BE27D6E43677A5" QueryPlanHash = "0x815C54EC43A6A6E9"
O Hash do plano de consulta está listado como um BINARY 8
- presumivelmente, esse deve sempre ter o mesmo comprimento, mas o que um cara como eu sabe sobre valores binários?
Brincando com o XQuery um pouco, descobri que, alterando a substring para iniciar na segunda posição, ele apresentava um valor de hash válido (embora incorreto).
WITH XMLNAMESPACES('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS p)
SELECT
QueryPlanCost = statement.value('sum(/p:StmtSimple/@StatementSubTreeCost)', 'float'),
**q.n.value('substring(@QueryPlanHash, 2)', 'BINARY(8)')**
FROM #statements s
CROSS APPLY s.statement.nodes('/p:StmtSimple') AS q(n)
OPTION(RECOMPILE);
WITH XMLNAMESPACES('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS p)
SELECT
QueryPlanCost = statement.value('sum(/p:StmtSimple/@StatementSubTreeCost)', 'float'),
**q.n.value('substring(@QueryPlanHash, 3)', 'BINARY(8)')**
FROM #statements s
CROSS APPLY s.statement.nodes('/p:StmtSimple') AS q(n)
OPTION(RECOMPILE);
Estou executando o SQL Server 2016, SP1 (13.0.4001).
Alguém já se deparou com isso antes?
17 caracteres têm um comprimento válido para um BINARY 8
valor?
Parece um bug que deve receber um item do Connect?