ทำไมการอ้างถึงตัวแปรในลูปที่ซ้อนกันของกำลังภาคบังคับ


16

ฉันเจอปัญหานี้เมื่อเร็ว ๆ นี้และไม่พบการสนทนาออนไลน์

แบบสอบถามด้านล่าง

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;

รับแผนลูปซ้อนกันเสมอ

ป้อนคำอธิบายรูปภาพที่นี่

การพยายามบังคับให้เกิดปัญหากับINNER HASH JOINหรือINNER MERGE JOINคำแนะนำจะทำให้เกิดข้อผิดพลาดดังต่อไปนี้

ตัวประมวลผลแบบสอบถามไม่สามารถสร้างแผนแบบสอบถามได้เนื่องจากคำแนะนำที่กำหนดไว้ในแบบสอบถามนี้ ส่งแบบสอบถามโดยไม่ระบุคำแนะนำใด ๆ และไม่ต้องใช้ SET FORCEPLAN

ฉันพบวิธีแก้ปัญหาที่อนุญาตให้ใช้การรวมแฮชหรือการผสาน - การรวมตัวแปรในการรวม แผนที่สร้างขึ้นนั้นมีต้นทุนที่ต่ำกว่าอย่างมาก (19.2025 เทียบกับ 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; 

ป้อนคำอธิบายรูปภาพที่นี่

อะไรคือสาเหตุของพฤติกรรมนี้? และมีวิธีแก้ปัญหาที่ดีกว่าที่ฉันพบ? (ซึ่งอาจไม่จำเป็นต้องมีสาขาแผนการดำเนินการพิเศษ)

คำตอบ:


13

ฉันได้ลองใช้แบบสอบถามของคุณกับอินสแตนซ์ SQL 2012 แล้วและติดตามการตั้งค่าสถานะ 4199 ดูเหมือนจะแก้ไขปัญหาได้ ด้วยการเปิดใช้งานฉันจะได้รับการรวมเข้าด้วยกันในราคา 0.24 และไม่มีสาขาพิเศษ

บทความ KB เฉพาะสำหรับปัญหานี้คือปัญหาประสิทธิภาพการทำงานเกิดขึ้นเมื่อเพรดิเคตเข้าร่วมในแบบสอบถามของคุณมีคอลัมน์อ้างอิงภายนอกใน SQL Server 2005 หรือใน SQL Server 2008

ป้อนคำอธิบายรูปภาพที่นี่

เพื่อให้มีคุณสมบัติเพิ่มเติม TF 4199 เปิดใช้งานการแก้ไขเครื่องมือเพิ่มประสิทธิภาพทั้งหมด ดูลิงค์นี้สำหรับข้อมูลเพิ่มเติม การเปิดใช้งานทุกอย่างในครั้งเดียวอาจมีผลข้างเคียงที่แปลกประหลาดดังนั้นหากคุณสามารถหาวิธีแก้ไขเฉพาะได้อาจเป็นการดีกว่าถ้าเปิดใช้งานการแก้ไขด้วยตนเอง

คุณสามารถเปิดใช้ธงร่องรอยบนพื้นฐานแบบสอบถามต่อการใช้OPTION (QUERYTRACEON 4199);


0

คำถามเก่า แต่การเห็นคำตอบนั้นไม่ชัดเจนนักฉันคิดว่าฉันจะหาวิธีแก้ปัญหาที่พบ ไม่แน่ใจว่าทำไมเครื่องมือเพิ่มประสิทธิภาพการค้นหาหยุดชะงักHASHแต่ฉันคิดว่าไม่ชอบMERGEเพราะไม่มีการเรียงลำดับอินพุต ในวันที่ 2012/14

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;

สร้างแผนดังต่อไปนี้:

ป้อนคำอธิบายรูปภาพที่นี่

บังคับTOPและORDER BYใน CTE MERGE JOINที่ดูเหมือนว่าจะให้ความรู้เพิ่มประสิทธิภาพเพียงพอเกี่ยวกับชุดข้อมูลในการดำเนินการ

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