AKTUALIZACJA: To zdecydowanie błąd. Aby uzyskać szczegółowe informacje, zobacz ten przedmiot Connect .
Podczas testowania niektórych zmian w sp_BlitzCache (pełne ujawnienie, jestem jednym z autorów), natknąłem się na coś, co moim zdaniem było błędem w naszym kodzie.
W pewnym momencie dopasowujemy skrót planu zapytania, aby uzyskać koszt zapytania. Robimy to tak:
statement.value('sum(/p:StmtSimple[xs:hexBinary(substring(@QueryHash, 3)) =
xs:hexBinary(sql:column("b.QueryHash"))]/@StatementSubTreeCost)', 'float')
O ile widziałem, to zadziałało. Jednak w jednym dziwnym przypadku podciąg w pliku XML generował NULL
wartość, a plan wykazywał koszt 0, mimo że był dość wysoki.
Zagłębiając się w plan wykonania (pełne ujawnienie, pracuję dla firmy, która jest gospodarzem Wklej plan), zauważyłem, że skrót planu zapytań dla jednego problemowego skrótu miał 17 znaków, a pozostałe 18. Oto przykłady:
QueryPlanHash = "0x4410B0CA640CDA89" QueryPlanHash = "0x2262FEA4CE645569" QueryPlanHash = "0xED4F225CC0E97E5" - Problem! QueryPlanHash = "0xBF878EEE6DB955EA" QueryPlanHash = "0x263B53BC8C14A452" QueryPlanHash = "0x89F5F146CF4B476F" QueryPlanHash = "0xEF47EA40805C8961" QueryPlanHash = "0xB7BE27D6E43677A5" QueryPlanHash = "0x815C54EC43A6A6E9"
Hash planu zapytań jest wymieniony jako BINARY 8
- przypuszczalnie powinna zawsze mieć tę samą długość, ale co taki facet jak ja wie o wartościach binarnych?
Grając trochę z XQuery, odkryłem, że zmieniając podłańcuch, aby rozpocząć od drugiej pozycji, uzyskałby prawidłową (choć niepoprawną) wartość skrótu.
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);
Korzystam z programu SQL Server 2016, SP1 (13.0.4001).
Czy ktoś już na to wpadł?
Czy 17 znaków jest prawidłową długością BINARY 8
wartości?
Czy to wygląda na błąd, który powinien otrzymać element Connect?
źródło