Neden bir birleşimde bir değişkene başvurmak iç içe döngülere zorlar?


16

Son zamanlarda bu sorunla karşılaştım ve çevrimiçi olarak herhangi bir tartışma bulamadım.

Aşağıdaki sorgu

DECLARE @S VARCHAR(1) = '';

WITH T
     AS (SELECT name + @S AS name2,
                *
         FROM   master..spt_values)
SELECT *
FROM   T T1
       INNER JOIN T T2
         ON T1.name2 = T2.name2;

Her zaman iç içe bir döngü planı alır

resim açıklamasını buraya girin

Sorunu INNER HASH JOINveya INNER MERGE JOINipuçlarını zorlamaya çalışmak aşağıdaki hatayı üretir.

Sorgu işlemcisi, bu sorguda tanımlanan ipuçları nedeniyle bir sorgu planı üretemedi. Herhangi bir ipucu belirtmeden ve SET FORCEPLAN kullanmadan sorguyu yeniden gönderin.

Değişken bir toplama içinde sarma karma veya birleştirme birleşimleri kullanılmasına izin veren bir geçici çözüm buldum. Oluşturulan plan önemli ölçüde daha düşük maliyetlidir (19.2025 ve 0.261987)

DECLARE @S2 VARCHAR(1) = '';

WITH T
     AS (SELECT name + (SELECT MAX(@S2)) AS name2,
                *
         FROM   spt_values)
SELECT *
FROM   T T1
       INNER JOIN T T2
         ON T1.name2 = T2.name2; 

resim açıklamasını buraya girin

Bu davranışın nedeni nedir? ve bulduğumdan daha iyi bir çözüm var mı? (bu belki de ekstra icra planı dallarını gerektirmez)

Yanıtlar:


13

Sorgunuzu bir SQL 2012 örneğinde denedim ve izleme bayrağı 4199 sorunu düzeltiyor gibi görünüyor. Etkinleştirildiğinde toplam 0.24 maliyet ve birleştirme şubelerinin hiçbiri için birleştirme birleşimi elde ederim.

Bu sorun için özel KB makalesi, performans sorunları, sorgunuzdaki birleştirme yüklemesi SQL Server 2005 veya SQL Server 2008'de dış başvuru sütunları olduğunda oluşur

resim açıklamasını buraya girin

Daha nitelikli olmak için TF 4199 tüm iyileştirici düzeltmelerini etkinleştirir. Daha fazla bilgi için bu bağlantıya bakın . Her şeyi aynı anda etkinleştirmek garip yan etkilere sahip olabilir, bu nedenle belirli bir düzeltme bulabilirseniz, düzeltmeyi kendi başına etkinleştirmek daha iyi olabilir.

İzleme bayrağını sorgu bazında etkinleştirerek OPTION (QUERYTRACEON 4199);


0

Eski soru, ama cevabı görmek süper kesin değildi, bulduğum bir geçici çözüm göndereceğini düşündüm. Sorgu iyileştirici neden balks emin değilim HASH, ama ben MERGEsıralama girdi çünkü beğenmez düşünüyorum . 2012/14 tarihinde,

DECLARE @S VARCHAR(1) = '';

    WITH T
        AS (SELECT TOP (2147483647)
                name + @S AS name2,
                *
            FROM   master..spt_values
            ORDER BY name + @S)
    SELECT *
    FROM   T T1
           INNER JOIN T T2
             ON T1.name2 = T2.name2;

aşağıdaki planı üretir:

resim açıklamasını buraya girin

Zorlama TOPve ORDER BYcte içinde optimizer gerçekleştirmek için veri kümesi hakkında yeterli bilgi vermek gibi görünüyor MERGE JOIN.

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.