SQL Server Query Plan XML: ความยาว QueryPlanHash


11

UPDATE:นี่เป็นข้อผิดพลาดอย่างแน่นอน สำหรับรายละเอียดทั้งหมดดูรายการเชื่อมต่อนี้

ในขณะที่ทดสอบการเปลี่ยนแปลงบางอย่างกับsp_BlitzCache (การเปิดเผยอย่างสมบูรณ์ฉันเป็นหนึ่งในผู้แต่ง) ฉันเจอสิ่งที่ฉันคิดว่าเป็นข้อบกพร่องในรหัสของเรา

ณ จุดหนึ่งเรากำลังจับคู่แฮชแผนแบบสอบถามเพื่อรับค่าใช้จ่ายแบบสอบถาม เราทำเช่นนั้นเกี่ยวกับเช่น:

statement.value('sum(/p:StmtSimple[xs:hexBinary(substring(@QueryHash, 3)) =
    xs:hexBinary(sql:column("b.QueryHash"))]/@StatementSubTreeCost)', 'float')

สิ่งนี้ได้ผลเท่าที่ฉันเคยเห็น อย่างไรก็ตามในกรณีที่แปลกหนึ่งสตริงย่อยใน XML กำลังส่งNULLค่าและแผนแสดงค่า 0 แม้ว่ามันจะค่อนข้างสูง

เมื่อขุดเข้าไปในแผนปฏิบัติการ (การเปิดเผยอย่างเต็มรูปแบบฉันทำงานให้กับ บริษัท ที่เป็นเจ้าภาพวางแผน) ฉันสังเกตเห็นว่าแฮชแผนแบบสอบถามสำหรับแฮชปัญหาเดียวมีแฮช 17 ตัวในขณะที่ที่เหลือคือ 18 นี่คือตัวอย่าง:

QueryPlanHash = "0x4410B0CA640CDA89"
QueryPlanHash = "0x2262FEA4CE645569" 
QueryPlanHash = "0xED4F225CC0E97E5" - ปัญหา!
QueryPlanHash = "0xBF878EEE6DB955EA"
QueryPlanHash = "0x263B53BC8C14A452"
QueryPlanHash = "0x89F5F146CF4B476F"
QueryPlanHash = "0xEF47EA40805C8961"
QueryPlanHash = "0xB7BE27D6E43677A5"
QueryPlanHash = "0x815C54EC43A6A6E9"

Query Plan Hash มีสถานะเป็นBINARY 8- สันนิษฐานว่านี่ควรเป็นความยาวเท่ากันเสมอ แต่ผู้ชายอย่างฉันรู้อะไรเกี่ยวกับค่าไบนารี

เล่นกับ XQuery นิดหน่อยฉันพบว่าการเปลี่ยน substring ให้เริ่มที่ตำแหน่งที่สองมันจะเกิดค่าแฮชที่ถูกต้อง (แม้ว่าจะไม่ถูกต้อง)

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ค่าหรือไม่

สิ่งนี้ดูเหมือนข้อบกพร่องที่ควรได้รับรายการเชื่อมต่อหรือไม่

คำตอบ:


11

ฉันคิดว่านี่เป็นสิ่งที่เกิดขึ้นเพราะแฮชตัวเดียวนั้นมีจำนวนอักขระแปลก ๆ ที่ถูกต้องVARBINARYจะต้องมี "คู่" จำนวนคู่เพื่อแสดงข้อมูลอย่างถูกต้อง ดังนั้น ... คุณควรจะสามารถที่จะแก้ปัญหานี้โดยการเอา0xวาง '0' ที่จุดเริ่มต้นโลภขวา 18 VARBINARYตัวอักษรแล้วเหวี่ยงลงสู่

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

ถ้าคุณต้องการบางสิ่งที่แข็งแกร่งกว่านี้ขอให้โชคดีเพราะคุณต้องหารด้วย 2 เป็นจำนวนเต็มและได้โมดูโลของ 2 จากนั้น "ทำสิ่งที่ถูกต้อง" เพื่อหาว่าข้อมูลของคุณควรใหญ่ขนาดไหน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.