UPDATE:これは間違いなくバグです。詳細については、 この接続項目 を参照してください。
sp_BlitzCache へのいくつかの変更をテストしているときに(完全な開示、私は作成者の1人です)、コードのバグだと思ったことに遭遇しました。
ある時点で、クエリコストを取得するためにクエリプランハッシュを照合しています。私たちはそのようにしています:
statement.value('sum(/p:StmtSimple[xs:hexBinary(substring(@QueryHash, 3)) =
xs:hexBinary(sql:column("b.QueryHash"))]/@StatementSubTreeCost)', 'float')
これは、私が見た限りではうまくいきました。ただし、奇妙なケースの1つとして、XMLの部分文字列がNULL
値をスローし、プランのコストがかなり高いにもかかわらず、コストが0でした。
実行計画 (完全な開示、Paste The Planをホストする会社で働いています)を掘り下げたところ、1つの問題のハッシュのクエリプランハッシュは17文字で、残りは18文字であることに気付きました。例は次のとおりです。
QueryPlanHash = "0x4410B0CA640CDA89" QueryPlanHash = "0x2262FEA4CE645569" QueryPlanHash = "0xED4F225CC0E97E5"-問題![.____。 QueryPlanHash = "0x815C54EC43A6A6E9"
クエリプランハッシュは リスト としてBINARY 8
-おそらくこれは常に同じ長さでなければなりませんが、私のような人はバイナリ値について何を知っていますか?
XQueryを少し試してみたところ、2番目の位置から開始するように部分文字列を変更すると、有効な(ただし正しくない)ハッシュ値が表示されることがわかりました。
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)を実行しています。
これまでに誰かに遭遇したことがありますか?
BINARY 8
値の有効な長さは17文字ですか?
これは、Connectアイテムを取得する必要があるバグのように見えますか?
これは、1つのハッシュが奇数の文字であるために起こっていると思います。有効なVARBINARY
は、データを正しく表すために偶数の「ペア」を持っている必要があります。ですから、0x
を削除し、最初に「0」を置き、右の18文字を取得して、VARBINARY
にキャストすることで、これを解決できるはずです。
CONVERT(VARBINARY(MAX), RIGHT('0' + SUBSTRING('0xED4F225CC0E97E5', 3, 20), 18), 2)
もっと頑強で幸運が必要な場合は、整数として2で除算し、2のモジュロを取得し、「正しいことを行う」ことでデータの大きさを把握する必要があるためです。