更新:这绝对是一个错误。有关详细信息,请参见此连接项。
在测试对sp_BlitzCache的一些更改(完整披露,我是作者之一)时,我遇到了我认为是代码中的错误的地方。
一方面,我们要匹配查询计划哈希以获取查询成本。我们这样做是这样的:
statement.value('sum(/p:StmtSimple[xs:hexBinary(substring(@QueryHash, 3)) =
xs:hexBinary(sql:column("b.QueryHash"))]/@StatementSubTreeCost)', 'float')
据我所知,这已经奏效了。但是,在一种奇怪的情况下,XML中的子字符串引发了一个NULL
值,尽管成本很高,但该计划的成本却显示为0。
深入研究执行计划(全面披露,我在负责Paste The Plan的公司工作),我注意到一个问题哈希的“查询计划哈希”长为17个字符,其余为18个字符。以下示例:
QueryPlanHash =“ 0x4410B0CA640CDA89” QueryPlanHash =“ 0x2262FEA4CE645569” QueryPlanHash =“ 0xED4F225CC0E97E5” –问题! QueryPlanHash =“ 0xBF878EEE6DB955EA” QueryPlanHash =“ 0x263B53BC8C14A452” QueryPlanHash =“ 0x89F5F146CF4B476F” QueryPlanHash =“ 0xEF47EA40805C8961” QueryPlanHash =“ 0xB7BE27D6E43677A5” QueryPlanHash =“ 0x815C54EC43A6A6E9”
查询计划哈希上市为BINARY 8
-想必这应该是相同的长度,但到底是什么像我这样的人了解二进制值?
稍微玩一下XQuery,我发现通过将子字符串更改为从第二个位置开始,它会得出一个有效的(尽管不正确)哈希值。
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);
我正在运行SQL Server 2016 SP1(13.0.4001)。
有人遇到过吗?
17个字符是BINARY 8
值的有效长度吗?
这看起来像应该获得Connect项目的bug吗?