Cập nhật:
Bài viết này trong blog của tôi tóm tắt cả câu trả lời và nhận xét của tôi cho một câu trả lời khác, đồng thời hiển thị các kế hoạch thực hiện thực tế:
SELECT *
FROM a
WHERE a.c IN (SELECT d FROM b)
SELECT a.*
FROM a
JOIN b
ON a.c = b.d
Các truy vấn này không tương đương. Chúng có thể mang lại các kết quả khác nhau nếu bảng của bạn b khóa không được bảo toàn (i. e. các giá trị của b.d không phải là duy nhất).
Tương đương với truy vấn đầu tiên như sau:
SELECT a.*
FROM a
JOIN (
SELECT DISTINCT d
FROM b
) bo
ON a.c = bo.d
Nếu b.d là UNIQUE và được đánh dấu như vậy (với UNIQUE INDEX hoặc UNIQUE CONSTRAINT ), thì các truy vấn này giống hệt nhau và hầu hết có thể sẽ sử dụng các gói giống hệt nhau, vì SQL Server đủ thông minh để tính đến điều này.
SQL Server có thể sử dụng một trong các phương pháp sau để chạy truy vấn này:
-
Nếu có một chỉ mục trên
a.c,dlàUNIQUEvàbtương đối nhỏ so vớia, sau đó điều kiện được truyền vào truy vấn con vàINNER JOINđơn giản được sử dụng (vớibdẫn đầu) -
Nếu có một chỉ mục trên
b.dvàdkhông phải làUNIQUE, thì điều kiện cũng được truyền vàLEFT SEMI JOINĐược sử dụng. Nó cũng có thể được sử dụng cho điều kiện trên. -
Nếu có một chỉ mục trên cả
b.dvàa.cvà chúng lớn, thìMERGE SEMI JOINđược sử dụng -
Nếu không có chỉ mục nào trên bất kỳ bảng nào, thì bảng băm được xây dựng trên
bvàHASH SEMI JOINđược sử dụng.
Không các phương pháp này đánh giá lại toàn bộ truy vấn con mỗi lần.
Xem mục này trong blog của tôi để biết thêm chi tiết về cách thức hoạt động:
Có các liên kết cho tất cả RDBMS của bốn người lớn.