LEFT JOIN
hoàn toàn không nhanh hơn INNER JOIN
. Trên thực tế, nó chậm hơn; theo định nghĩa, một phép nối ngoài (LEFT JOIN
hoặc RIGHT JOIN
) phải thực hiện tất cả công việc của một INNER JOIN
cộng với công việc bổ sung của việc mở rộng kết quả vô hiệu. Nó cũng sẽ trả về nhiều hàng hơn, tăng tổng thời gian thực thi chỉ đơn giản là do kích thước tập hợp kết quả lớn hơn.
(Và ngay cả khi LEFT JOIN
was nhanh hơn trong cụ thể các tình huống do một số yếu tố kết hợp khó hình dung, nó không tương đương về mặt chức năng với INNER JOIN
, vì vậy bạn không thể đơn giản thay thế tất cả các bản sao của cái này bằng cái kia!)
Nhiều khả năng các vấn đề về hiệu suất của bạn nằm ở chỗ khác, chẳng hạn như không có khóa ứng viên hoặc khóa ngoại được lập chỉ mục đúng cách. 9 bàn là khá nhiều người tham gia nên sự chậm lại có thể gần như ở bất cứ đâu. Nếu bạn đăng giản đồ của mình, chúng tôi có thể cung cấp thêm chi tiết.
Chỉnh sửa:
Suy ngẫm thêm về điều này, tôi có thể nghĩ đến một trường hợp mà theo đó LEFT JOIN
có thể nhanh hơn INNER JOIN
và đó là khi:
- Một số bảng rất nhỏ (giả sử dưới 10 hàng);
- Các bảng không có đủ chỉ mục để bao gồm truy vấn.
Hãy xem xét ví dụ này:
CREATE TABLE #Test1
(
ID int NOT NULL PRIMARY KEY,
Name varchar(50) NOT NULL
)
INSERT #Test1 (ID, Name) VALUES (1, 'One')
INSERT #Test1 (ID, Name) VALUES (2, 'Two')
INSERT #Test1 (ID, Name) VALUES (3, 'Three')
INSERT #Test1 (ID, Name) VALUES (4, 'Four')
INSERT #Test1 (ID, Name) VALUES (5, 'Five')
CREATE TABLE #Test2
(
ID int NOT NULL PRIMARY KEY,
Name varchar(50) NOT NULL
)
INSERT #Test2 (ID, Name) VALUES (1, 'One')
INSERT #Test2 (ID, Name) VALUES (2, 'Two')
INSERT #Test2 (ID, Name) VALUES (3, 'Three')
INSERT #Test2 (ID, Name) VALUES (4, 'Four')
INSERT #Test2 (ID, Name) VALUES (5, 'Five')
SELECT *
FROM #Test1 t1
INNER JOIN #Test2 t2
ON t2.Name = t1.Name
SELECT *
FROM #Test1 t1
LEFT JOIN #Test2 t2
ON t2.Name = t1.Name
DROP TABLE #Test1
DROP TABLE #Test2
Nếu bạn chạy cái này và xem kế hoạch thực thi, bạn sẽ thấy rằng INNER JOIN
truy vấn thực sự có giá cao hơn LEFT JOIN
, vì nó thỏa mãn hai tiêu chí trên. Đó là bởi vì SQL Server muốn thực hiện đối sánh băm cho INNER JOIN
, nhưng có các vòng lặp lồng nhau cho LEFT JOIN
; trước đây là bình thường nhanh hơn nhiều, nhưng vì số lượng hàng rất nhỏ và không có chỉ mục nào để sử dụng, hoạt động băm hóa ra là phần đắt nhất của truy vấn.
Bạn có thể thấy hiệu ứng tương tự bằng cách viết một chương trình bằng ngôn ngữ lập trình yêu thích của bạn để thực hiện một số lượng lớn tra cứu trên danh sách có 5 phần tử, so với bảng băm có 5 phần tử. Do kích thước, phiên bản bảng băm thực sự chậm hơn. Nhưng hãy tăng nó lên 50 phần tử hoặc 5000 phần tử và phiên bản danh sách chậm thu thập thông tin, vì nó là O (N) so với O (1) cho bảng băm.
Nhưng thay đổi truy vấn này thành ID
thay vì Name
và bạn sẽ thấy một câu chuyện rất khác. Trong trường hợp đó, nó thực hiện các vòng lặp lồng nhau cho cả hai truy vấn, nhưng INNER JOIN
phiên bản có thể thay thế một trong các lần quét chỉ mục theo cụm bằng một lần tìm kiếm - nghĩa là đây thực sự sẽ là một thứ tự độ lớn nhanh hơn với số lượng lớn hàng.
Vì vậy, kết luận ít nhiều là những gì tôi đã đề cập đến một số đoạn ở trên; đây gần như chắc chắn là một vấn đề về lập chỉ mục hoặc phạm vi lập chỉ mục, có thể được kết hợp với một hoặc nhiều bảng rất nhỏ. Đó là những trường hợp duy nhất mà SQL Server có thể đôi khi chọn một kế hoạch thực thi kém hơn cho INNER JOIN
hơn một LEFT JOIN
.