ОБНОВЛЕНИЕ: Это определенно ошибка. Для получения полной информации см. Этот пункт подключения .
При тестировании некоторых изменений в 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"
План запроса Hash указан как 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 с пакетом обновления 1 (13.0.4001).
Кто-нибудь сталкивался с этим раньше?
Является ли 17 символов допустимой длиной для BINARY 8
значения?
Похоже ли это на ошибку, которая должна получить элемент Connect?