SQL Server Sorgu Planı XML: QueryPlanHash Uzunluğu


11

GÜNCELLEME: Bu kesinlikle bir hata. Tüm ayrıntılar için bu Bağlantı Öğesine bakın .

Sp_BlitzCache (tam açıklama, yazarlardan biriyim) bazı değişiklikleri test ederken, kodumuzda bir hata olduğunu düşündüm ne rastladı.

Bir noktada, sorgu maliyeti elde etmek için Sorgu Planı Karması ile eşleşiyoruz. Bunu şu şekilde yapıyoruz:

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

Bu gördüğüm kadarıyla işe yaradı. Ancak, garip bir durumda, XML'deki alt dize bir NULLdeğer atıyordu ve plan oldukça yüksek olmasına rağmen 0 maliyeti gösteriyordu.

İçine Kazı yürütme planı (tam açıklama, ana Planı Yapıştır o şirket için ben iş), ben Sorgu Planı Hash bir problem karma için dinlenme 18. İşte örnekler ise, 17 karakter uzunluğunda olduğunu fark:

QueryPlanHash = "0x4410B0CA640CDA89"
QueryPlanHash = "0x2262FEA4CE645569" 
QueryPlanHash = "0xED4F225CC0E97E5" - Sorun!
QueryPlanHash = "0xBF878EEE6DB955EA"
QueryPlanHash = "0x263B53BC8C14A452"
QueryPlanHash = "0x89F5F146CF4B476F"
QueryPlanHash = "0xEF47EA40805C8961"
QueryPlanHash = "0xB7BE27D6E43677A5"
QueryPlanHash = "0x815C54EC43A6A6E9"

Sorgu Planı Hash olduğu belirtilen bir şekilde BINARY 8muhtemelen bu her zaman aynı uzunlukta olmalı, ama benim gibi bir adam ikili değerleri hakkında ne bilir ki? -

Biraz XQuery ile oynamak, ben ikinci konumda başlamak için alt dize değiştirerek, geçerli (yanlış da olsa) karma değeri ile buldum bulundu.

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);

Fındık

SQL Server 2016, SP1 (13.0.4001) kullanıyorum.

Daha önce birisi bunun üzerinde çalıştı mı?

17 karakter bir BINARY 8değer için geçerli bir uzunluk mu?

Bu, Connect öğesi alması gereken bir hata gibi mi görünüyor?

Yanıtlar:


11

Bence bu oluyor çünkü bir karma tek sayıda karakter. Geçerli VARBINARYbir veriyi doğru bir şekilde temsil etmek için çift sayıda "çift" olması gerekir. Yani ... bunu 0xçözerek, başlangıçta bir '0' koyarak, doğru 18 karakteri alıp üzerine yazarak çözebilmelisin VARBINARY.

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

Daha sağlam, iyi şanslar istiyorsanız, tamsayı olarak 2'ye bölmeniz ve 2 modulounu almanız ve ardından verilerinizin ne kadar büyük olması gerektiğini anlamak için "doğru olanı" yapmanız gerekir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.