Tại sao tham chiếu một biến trong một vòng lặp vị ngữ tham gia lực lượng lồng nhau?


16

Tôi đã gặp vấn đề này gần đây và không thể tìm thấy bất kỳ cuộc thảo luận nào về nó trực tuyến.

Các truy vấn dưới đây

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;

Luôn luôn có một kế hoạch vòng lặp lồng nhau

nhập mô tả hình ảnh ở đây

Cố gắng buộc vấn đề với INNER HASH JOINhoặc INNER MERGE JOINgợi ý tạo ra lỗi sau.

Bộ xử lý truy vấn không thể tạo ra một kế hoạch truy vấn vì các gợi ý được xác định trong truy vấn này. Gửi lại truy vấn mà không chỉ định bất kỳ gợi ý nào và không sử dụng SET FORCEPLAN.

Tôi đã tìm thấy một cách giải quyết cho phép băm hoặc hợp nhất các phép nối được sử dụng - gói biến trong một tổng hợp. Gói được tạo ra có chi phí thấp hơn đáng kể (19,2025 so với 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; 

nhập mô tả hình ảnh ở đây

Lý do cho hành vi này là gì? và có một cách giải quyết tốt hơn so với cái mà tôi tìm thấy? (có lẽ không yêu cầu các nhánh kế hoạch thực hiện thêm)

Câu trả lời:


13

Tôi đã thử truy vấn của bạn trên phiên bản SQL 2012 và cờ theo dõi 4199 dường như để khắc phục sự cố. Với nó được kích hoạt, tôi có được một phép nối hợp nhất với tổng chi phí là 0,24 và không có chi nhánh nào.

Bài viết KB cụ thể cho vấn đề này là Sự cố hiệu suất xảy ra khi vị từ nối trong truy vấn của bạn có các cột tham chiếu bên ngoài trong SQL Server 2005 hoặc trong SQL Server 2008

nhập mô tả hình ảnh ở đây

Để tiếp tục đủ điều kiện, TF 4199 cho phép tất cả các bản sửa lỗi tối ưu hóa. Xem liên kết này để biết thêm thông tin. Kích hoạt mọi thứ cùng một lúc có thể có tác dụng phụ kỳ lạ, vì vậy nếu bạn có thể tìm thấy một bản sửa lỗi cụ thể, có thể tốt hơn là tự mình sửa bản sửa lỗi.

Bạn có thể bật cờ theo dõi trên cơ sở mỗi truy vấn bằng cách sử dụng OPTION (QUERYTRACEON 4199);


0

Câu hỏi cũ, nhưng nhìn thấy câu trả lời không quá dứt khoát, tôi nghĩ rằng tôi sẽ đăng một cách giải quyết mà tôi tìm thấy. Không chắc chắn tại sao trình tối ưu hóa truy vấn chùn bước HASH, nhưng tôi nghĩ nó không thích MERGEbởi vì nó không có đầu vào được sắp xếp. Vào ngày 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;

tạo ra kế hoạch sau:

nhập mô tả hình ảnh ở đây

Buộc TOPORDER BYtrong cte dường như cung cấp cho trình tối ưu hóa đủ kiến ​​thức về bộ dữ liệu để thực hiện MERGE JOIN.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.