Truy vấn con tương quan và tham gia: vẫn cùng một kế hoạch ngoại lệ?


7

Tôi có một truy vấn con tương quan như thế này (từ BOL ):

SELECT DISTINCT c.LastName, c.FirstName, e.BusinessEntityID 
FROM Person.Person AS c JOIN HumanResources.Employee AS e
ON e.BusinessEntityID = c.BusinessEntityID 
WHERE 5000.00 IN
    (SELECT Bonus
    FROM Sales.SalesPerson sp
    WHERE e.BusinessEntityID = sp.BusinessEntityID) ;
GO

Khi tôi viết lại truy vấn này bằng cách sử dụng tham gia

select c.LastName, c.FirstName, e.BusinessEntityID, d.Bonus
from Person.Person as c 
    inner join HumanResources.Employee as e on e.BusinessEntityID = c.BusinessEntityID
    inner join Sales.SalesPerson as d on d.BusinessEntityID = c.BusinessEntityID
where Bonus = 5000.00

Và nhìn vào kế hoạch thực hiện thực tế, nó trông giống hệt nhau trong cả hai truy vấn. Tại sao? Tôi đã nghĩ rằng truy vấn con tương quan chậm hơn nhiều do vòng lặp lồng nhau và kế hoạch thực hiện có khác nhau không? Có phải vì không có nhiều dữ liệu trong các bảng này?


Vâng, có, nhưng tại sao họ mang lại kế hoạch thực hiện tương tự?
jrara

2
Bởi vì trình tối ưu hóa đủ thông minh để phát hiện tình huống. Không có gì lạ khi các lựa chọn phụ và liên kết phụ (tham gia) mang lại cùng một kế hoạch nếu có thể.
a_horse_with_no_name

Vui lòng cung cấp đầu ra EXPLAIN của các SQL gốc và viết lại. Ngoài ra, cung cấp thông tin TÌNH TRẠNG SHOW TẠO và SHOW TABLE cho mỗi bảng

@Aftab Xin vui lòng không gửi thêm bất kỳ bình luận nào dưới dạng câu trả lời. Chúng tôi có một chức năng bình luận cho một lý do.
JNK

2
@Aftab: Câu hỏi này được gắn thẻ [sql-server], không [mysql].
ypercubeᵀᴹ

Câu trả lời:


11

Hai truy vấn giống hệt nhau và tạo ra cùng một kế hoạch. Giai đoạn đơn giản hóa của Trình tối ưu hóa truy vấn xử lý việc này.

Chúng giống hệt nhau vì các ràng buộc trên bảng - khóa ngoại, tính duy nhất, tính vô hiệu ...


5

Một trình tối ưu hóa tốt sẽ nhận ra khi nào một truy vấn tương quan có thể được viết dưới dạng tham gia và sử dụng cùng một kế hoạch. Nhiều truy vấn tương quan có thể dễ dàng được viết như một tham gia. Trong trường hợp này, trình tối ưu hóa đang thực hiện công việc của nó. Tối ưu hóa truy vấn theo cách này cho phép các kế hoạch sẽ không có ý nghĩa khi sử dụng truy vấn tương quan.

Tôi có xu hướng viết một truy vấn tương quan khi nó có ý nghĩa về mặt ngữ nghĩa và sử dụng phép nối khi điều đó phù hợp về mặt ngữ nghĩa. Tối ưu hóa hiện đại sẽ tạo ra các truy vấn thích hợp. Khi trình tối ưu hóa được cải thiện, sau đó tôi sẽ viết các truy vấn để dễ hiểu và không cố gắng đoán lần thứ hai trình tối ưu hóa. (Tôi thấy trình tối ưu hóa thường hoạt động tốt hơn dù sao đi nữa. Có một số trường hợp hiếm hoi tôi biết điều gì đó mà trình tối ưu hóa không thể xác định được từ truy vấn.)

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.