SQL Server查询计划XML:QueryPlanHash长度


11

更新:这绝对是一个错误。有关详细信息,请参见此连接项

在测试对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吗?

Answers:


11

我认为这是因为一个哈希值是奇数个字符而发生的。有效值VARBINARY将需要偶数个“对”才能正确表示数据。因此...您应该能够解决此问题,方法是删除0x,在开头放置一个“ 0”,抓住正确的18个字符,然后将其强制转换为VARBINARY

CONVERT(VARBINARY(MAX), RIGHT('0' + SUBSTRING('0xED4F225CC0E97E5', 3, 20), 18), 2)

如果您想要更健壮的东西,祝您好运,因为您需要将2除以整数,然后取2的模,然后“做正确的事”来确定数据应该有多大。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.