SQL सर्वर क्वेरी योजना XML: QueryPlanHash लंबाई


11

अद्यतन: यह निश्चित रूप से एक बग है। पूर्ण विवरण के लिए यह कनेक्ट आइटम देखें ।

Sp_BlitzCache (पूर्ण प्रकटीकरण, मैं लेखकों में से एक हूं) में कुछ परिवर्तनों का परीक्षण करते समय , मुझे लगा कि मेरे कोड में एक बग क्या था।

एक बिंदु पर, हम क्वेरी लागत प्राप्त करने के लिए क्वेरी प्लान हैश का मिलान कर रहे हैं। हम ऐसा करते हैं:

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

यह है, जहाँ तक मैंने देखा है, काम किया है। हालांकि, एक अजीब मामले में, एक्सएमएल में सबस्ट्रिंग एक NULLमूल्य फेंक रहा था , और योजना 0 की लागत दिखा रही थी, इसके बावजूद यह अधिक था।

निष्पादन योजना (पूर्ण प्रकटीकरण में खुदाई , मैं उस कंपनी के लिए काम करता हूं जो पेस्ट योजना को होस्ट करता है), मैंने देखा कि एक समस्या हैश के लिए क्वेरी प्लान हैश 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 सर्वर 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 का मॉडुलो प्राप्त करें, और फिर "सही काम करें" यह पता लगाने के लिए कि आपका डेटा कितना बड़ा होना चाहिए।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.