Tại sao các truy vấn tương tự này sử dụng các giai đoạn tối ưu hóa khác nhau (xử lý giao dịch so với kế hoạch nhanh)?


12

Mã ví dụ trong mục kết nối này

Hiển thị một lỗi trong đó

SELECT COUNT(*)
FROM   dbo.my_splitter_1('2') L1
       INNER JOIN dbo.my_splitter_1('') L2
         ON L1.csv_item = L2.csv_item

Trả về kết quả chính xác. Nhưng những điều sau đây trả về kết quả không chính xác (vào năm 2014 bằng cách sử dụng Công cụ ước tính Cardinality mới)

SELECT
    (SELECT COUNT(*)
    FROM dbo.my_splitter_1('2') L1
     INNER JOIN dbo.my_splitter_1('') L2
        ON L1.csv_item = L2.csv_item)

Vì nó tải không chính xác các kết quả cho L2 vào một bộ đệm biểu thức con chung sau đó phát lại kết quả của kết quả đó cho kết quả L1.

Tôi tò mò về lý do tại sao sự khác biệt trong hành vi giữa hai truy vấn. Trace Flag 8675 cho thấy cái nào hoạt động được search(0) - transaction processingvà cái bị hỏng search(1) - quick plan.

Vì vậy, tôi cho rằng sự sẵn có của các quy tắc chuyển đổi bổ sung đằng sau sự khác biệt trong hành vi (vô hiệu hóa BuildGbApply hoặc GenGbApplySimple dường như để khắc phục nó chẳng hạn).

Nhưng tại sao hai kế hoạch cho các truy vấn rất giống nhau này gặp phải các giai đoạn tối ưu hóa khác nhau? Từ những gì tôi đã đọc search (0)yêu cầu ít nhất ba bảng và điều kiện đó chắc chắn không được đáp ứng trong ví dụ đầu tiên.

Câu trả lời:


7

Mỗi giai đoạn có điều kiện nhập cảnh. "Có ít nhất ba tham chiếu bảng" là một trong những điều kiện đầu vào mà chúng ta nói đến khi đưa ra các ví dụ đơn giản, nhưng đó không phải là điều duy nhất.

Nói chung, chỉ các phép nối và liên kết cơ bản mới được phép vào mục tìm kiếm 0; truy vấn vô hướng, bán tham gia, vv ngăn chặn việc tìm kiếm 0. Giai đoạn này thực sự dành cho các hình dạng truy vấn kiểu OLTP rất phổ biến. Các quy tắc cần thiết để khám phá những điều ít phổ biến hơn không được kích hoạt. Truy vấn ví dụ của bạn có một truy vấn con vô hướng, vì vậy nó không nhập được.

Nó cũng phụ thuộc vào cách bạn đếm tài liệu tham khảo bảng. Tôi chưa bao giờ nhìn sâu vào vấn đề này với các hàm, nhưng có thể logic đang đếm các Hàm có giá trị của Bảng cũng như các biến bảng mà chúng tạo ra. Nó thậm chí có thể đếm tham chiếu bảng bên trong hàm - tôi không chắc chắn; mặc dù tôi biết rằng các chức năng chỉ là công việc khó khăn tất cả các vòng.

Các lỗi với GenGbApplySimplelà xấu xí. Hình dạng kế hoạch này luôn có khả năng, nhưng bị từ chối vì lý do chi phí cho đến khi thay đổi thành số lượng thẻ biến đổi bảng giả định 100 hàng USE PLAN. Ví dụ, có thể buộc hình dạng kế hoạch có vấn đề trên CE trước năm 2014 bằng một gợi ý.

Bạn đã đúng về mục Kết nối mới là vấn đề tương tự được báo cáo trước đây .

Để cung cấp một ví dụ, truy vấn sau đủ điều kiện cho tìm kiếm 0:

DECLARE @T AS table (c1 integer NULL);

SELECT U.c1, rn = ROW_NUMBER() OVER (ORDER BY U.c1) 
FROM 
(
    SELECT c1 FROM @T AS T
    UNION
    SELECT c1 FROM @T AS T
    UNION
    SELECT c1 FROM @T AS T
) AS U;

Thực hiện một thay đổi nhỏ để bao gồm một truy vấn con vô hướng có nghĩa là nó đi thẳng vào tìm kiếm 1:

DECLARE @T AS table (c1 integer NULL);

SELECT U.c1, rn = ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -- Changed!
FROM 
(
    SELECT c1 FROM @T AS T
    UNION
    SELECT c1 FROM @T AS T
    UNION
    SELECT c1 FROM @T AS T
) AS U;
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.