Tại sao ước tính hàng SQL Server thay đổi khi tôi thêm gợi ý tham gia?


15

Tôi có một truy vấn tham gia một vài bảng và thực hiện khá tệ - ước tính hàng bị tắt (1000 lần) và tham gia Vòng lặp lồng nhau được chọn, dẫn đến quét nhiều bảng. Hình dạng của truy vấn khá đơn giản, trông giống như thế này:

SELECT t1.id
FROM t1
INNER JOIN t2 ON t1.id = t2.t1_id
LEFT OUTER JOIN t3 ON t2.id = t3.t2_id
LEFT OUTER JOIN t4 ON t3.t4_id = t4.id 
WHERE t4.id = some_GUID

Chơi xung quanh với truy vấn, tôi nhận thấy rằng khi tôi gợi ý nó sử dụng phép nối Hợp nhất cho một trong các phép nối, nó chạy nhanh hơn nhiều lần. Điều này tôi có thể hiểu - Hợp nhất tham gia là một tùy chọn tốt hơn cho dữ liệu được tham gia, nhưng SQL Server chỉ không ước tính đúng khi chọn Vòng lặp lồng nhau.

Điều tôi không hiểu đầy đủ là tại sao gợi ý tham gia này thay đổi tất cả các ước tính cho tất cả các nhà khai thác kế hoạch? Từ việc đọc các bài báo và sách khác nhau, tôi giả định rằng các ước tính cardinality được thực hiện trước khi kế hoạch được xây dựng, do đó, việc sử dụng một gợi ý sẽ không thay đổi các ước tính, nhưng nói rõ ràng với SQL Server để sử dụng triển khai tham gia vật lý cụ thể.

Tuy nhiên, những gì tôi thấy là gợi ý Hợp nhất làm cho tất cả các ước tính trở nên khá hoàn hảo. Tại sao điều này xảy ra và có bất kỳ kỹ thuật phổ biến nào để tối ưu hóa truy vấn đưa ra ước tính tốt hơn mà không có gợi ý - xem xét rằng thống kê rõ ràng cho phép điều này?

CẬP NHẬT: các kế hoạch thực hiện ẩn danh có thể được tìm thấy ở đây: https://www.dropbox.com/s/hchfuru35qqj89s/merge_join.sqlplan?dl=0 https://www.dropbox.com/s/38sjtv0t7vjjfdp/no_hints_join.s = 0

Tôi đã kiểm tra các số liệu thống kê được sử dụng bởi cả hai truy vấn bằng TF 3604, 9292 và 9204 và các truy vấn này giống hệt nhau. Tuy nhiên, các chỉ mục được quét / tìm kiếm khác nhau giữa các truy vấn.

Ngoài ra, tôi đã thử chạy truy vấn với OPTION (FORCE ORDER)- nó chạy nhanh hơn cả sử dụng phép nối, chọn HASH MATCH cho mỗi lần nối.


3
Bạn có nhận thấy rằng bạn có một tham gia bên ngoài nhưng sau đó bạn đang sử dụng bảng trong mệnh đề where?
James Z

@JamesZ - vâng, tôi biết điều đó, mặc dù vậy tôi không nghĩ có vấn đề gì với điều đó.
Alexander Shelemin

9
@AlexSh Vâng, có một vấn đề logic / ngữ nghĩa với điều đó, bởi vì điều đó thay đổi kết nối bên ngoài của bạn thành một tham gia bên trong.
Aaron Bertrand

Câu trả lời:


21

Từ việc đọc các bài báo và sách khác nhau, tôi giả định rằng các ước tính về tim mạch được thực hiện trước khi kế hoạch được xây dựng.

Không chính xác. Một ước tính cardinality ban đầu được lấy (sau khi đơn giản hóa và công việc khác), ảnh hưởng đến thứ tự tham gia ban đầu được chọn bởi trình tối ưu hóa.

Tuy nhiên, các khám phá tiếp theo (trong quá trình tối ưu hóa dựa trên chi phí) có thể và thường làm dẫn đến các ước tính về số lượng thẻ mới được tính toán. Những CE sau này có thể ít nhiều 'chính xác'. Nếu kết quả ước tính thấp, trình tối ưu hóa có thể chọn gói có vẻ rẻ hơn, nhưng thực tế lại chạy lâu hơn nhiều.

Nói chung, không có gì đảm bảo rằng các ước tính cardinality cho các cây con giống hệt nhau về mặt ngữ nghĩa sẽ tạo ra kết quả tương tự. Rốt cuộc, đây là một quy trình thống kê và một số hoạt động có hỗ trợ CE sâu hơn các hoạt động khác.

Trong trường hợp của bạn, dường như có một yếu tố khác - trình tối ưu hóa giới thiệu (hoặc di chuyển xung quanh) một Top, đặt mục tiêu hàng trên cây con bên dưới nó:

Kế hoạch mảnh

Nếu bạn đã bật cờ theo dõi 4138 (trên 2008 R2 trở lên), bạn có thể thấy các ước tính phù hợp hơn với mong đợi hoặc thậm chí có thể là trình tối ưu hóa sẽ không còn chọn các vòng lặp lồng nhau.

Tuy nhiên, những gì tôi thấy là gợi ý Hợp nhất làm cho tất cả các ước tính trở nên khá hoàn hảo.

Có một yếu tố may mắn liên quan ở đây. Mọi người có xu hướng viết các truy vấn, hoặc ít nhất là các phép nối, theo thứ tự họ mong đợi chúng được thực hiện một cách vật lý. Sử dụng một gợi ý tham gia đi kèm với một hàm ý FORCE ORDER, do đó sửa lỗi thứ tự nối để khớp với hình thức văn bản và tắt nhiều quy tắc thăm dò tối ưu hóa có thể dẫn đến ước tính lại cardinality.

Ngoài ra, tôi đã thử chạy truy vấn với OPTION (FORCE ORDER)- nó chạy nhanh hơn cả sử dụng phép nối, chọn HASH MATCH cho mỗi lần nối.

Điều này giống như gợi ý một phép nối, nhưng không hạn chế sự lựa chọn của toán tử nối vật lý. Một lần nữa, nếu bạn tình cờ viết thứ tự tham gia truy vấn một cách hợp lý, rất có khả năng bạn sẽ có được một kế hoạch hợp lý. Tất nhiên, bạn bỏ lỡ nhiều khả năng của trình tối ưu hóa theo cách này, điều này có thể không tạo ra kết quả tối ưu trong các tình huống chung hơn.

Bạn có thể sẽ không muốn sử dụng FORCE ORDERrất thường xuyên vì đây là một gợi ý cực kỳ mạnh mẽ (chỉ thị) có hiệu ứng rộng hơn so với việc đơn giản buộc thứ tự tham gia; ví dụ, nó ngăn chặn trình tối ưu hóa di chuyển các tập hợp xung quanh và giới thiệu các tập hợp một phần. Tôi rất khuyên bạn không nên sử dụng gợi ý này trừ những trường hợp rất đặc biệt và bởi những người điều chỉnh thực sự chuyên nghiệp .

Một phân tích chi tiết sẽ cần nhiều thời gian hơn tôi có ngay bây giờ và truy cập vào một bản sao chỉ thống kê của cơ sở dữ liệu.


-10

Trường hợp phủ định bên trái
Tại sao làm cho nó tối ưu hóa?
Tại 3 hoặc nhiều hơn tham gia tôi ưu hoa sẽ có xu hướng đi phòng thủ và vào vòng tham gia như bảo vệ bộ nhớ
Một hoặc điều kiện trong tham gia nó cũng sẽ có xu hướng đi vào một vòng lặp tham gia - Tôi có bằng chứng cứng nó sẽ xảy ra mỗi khi - không - vẫn là một thực tế
Với nhiều điều kiện tham gia kéo các điều kiện từ nơi tham gia khi bạn có thể

SELECT t1.id
  FROM t1
  JOIN t2 
        ON t1.id = t2.t1_id
  JOIN t3 
        ON t2.id = t3.t2_id
  JOIN t4 
        ON t3.t4_id = t4.id 
       AND t4.id = some_GUID 

Hoặc thậm chí tốt hơn nữa - Tôi cá rằng điều này sẽ đáp ứng hoặc đánh bại gợi ý hoặc lực lượng của bạn

SELECT t1.id
  FROM t1
  JOIN t2 
        ON t1.id = t2.t1_id
  JOIN t3 
        ON t2.id = t3.t2_id
       AND t3.t4_id = some_GUID

Vấn đề với gợi ý là chúng dành cho dữ liệu ở trạng thái cụ thể. Viết một truy vấn sạch và để trình tối ưu hóa thực hiện công việc của nó. Đôi khi nó chỉ cần thêm số liệu thống kê để làm điều đúng nhưng sau đó nó sẽ khóa.

Tại sao ước tính khác nhau. Một kế hoạch khác. Bắt đầu với các truy vấn cung cấp cho trình tối ưu hóa một cơ hội chiến đấ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.