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
,d
làUNIQUE
vàb
tươ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ớib
dẫn đầu) -
Nếu có một chỉ mục trên
b.d
vàd
khô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.d
vàa.c
và 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
b
và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.