Tôi có một trường hợp sử dụng THAM GIA hoặc IN sẽ cho tôi kết quả chính xác ... Cái nào thường có hiệu suất tốt hơn và tại sao? Bao nhiêu nó phụ thuộc vào máy chủ cơ sở dữ liệu bạn đang chạy? (FYI tôi đang sử dụng MSSQL)
Tôi có một trường hợp sử dụng THAM GIA hoặc IN sẽ cho tôi kết quả chính xác ... Cái nào thường có hiệu suất tốt hơn và tại sao? Bao nhiêu nó phụ thuộc vào máy chủ cơ sở dữ liệu bạn đang chạy? (FYI tôi đang sử dụng MSSQL)
Câu trả lời:
Nói chung, IN
và JOIN
là các truy vấn khác nhau có thể mang lại kết quả khác nhau.
SELECT a.*
FROM a
JOIN b
ON a.col = b.col
không giống như
SELECT a.*
FROM a
WHERE col IN
(
SELECT col
FROM b
)
, trừ khi b.col
là duy nhất.
Tuy nhiên, đây là từ đồng nghĩa cho truy vấn đầu tiên:
SELECT a.*
FROM a
JOIN (
SELECT DISTINCT col
FROM b
)
ON b.col = a.col
Nếu cột tham gia là UNIQUE
và được đánh dấu như vậy, cả hai truy vấn này đều có cùng một kế hoạch SQL Server
.
Nếu không, thì IN
nhanh hơn JOIN
trên DISTINCT
.
Xem bài viết này trong blog của tôi để biết chi tiết hiệu suất:
IN
ngụ ý DISTINCT
. SQL Server
đủ thông minh để nhận ra điều đó và sẽ tạo ra các kế hoạch giống nhau cho cả hai truy vấn. Tuy nhiên, không chắc chắn, những người khác RDBMS
sẽ cư xử như thế nào .
Thật buồn cười khi bạn đề cập đến điều đó, tôi đã viết một bài blog về chính chủ đề này.
Xem Oracle vs MySQL vs SQL Server: Hợp nhất với Joins
Câu trả lời ngắn: bạn phải kiểm tra nó và cơ sở dữ liệu cá nhân khác nhau rất nhiều.
Điều đó khá khó để nói - để thực sự tìm ra cái nào hoạt động tốt hơn, bạn cần phải thực sự xác định thời gian thực hiện.
Theo nguyên tắc chung, tôi nghĩ rằng nếu bạn có chỉ số trên các cột khóa ngoại của mình và nếu bạn chỉ sử dụng (hoặc chủ yếu) các điều kiện INNER THAM GIA, thì THAM GIA sẽ nhanh hơn một chút.
Nhưng ngay khi bạn bắt đầu sử dụng OUTER THAM GIA hoặc nếu bạn thiếu chỉ mục khóa ngoại, IN có thể nhanh hơn.
Marc
Một bài viết thú vị về sự khác biệt logic: SQL Server: THAM GIA vs IN vs EXISTS - sự khác biệt logic
Tôi khá chắc chắn rằng giả định rằng các mối quan hệ và chỉ mục được duy trì Tham gia sẽ hoạt động tổng thể tốt hơn (nhiều nỗ lực hơn để làm việc với hoạt động đó sau đó là các hoạt động khác). Nếu bạn nghĩ về nó về mặt khái niệm thì đó là sự khác biệt giữa 2 truy vấn và 1 truy vấn.
Bạn cần nối nó với Trình phân tích truy vấn và thử nó và xem sự khác biệt. Đồng thời nhìn vào Kế hoạch thực hiện truy vấn và cố gắng giảm thiểu các bước.
Chủ đề này khá cũ nhưng vẫn được đề cập thường xuyên. Đối với sở thích cá nhân của tôi, nó không đầy đủ một chút, bởi vì có một cách khác để hỏi cơ sở dữ liệu với từ khóa EXISTS mà tôi thấy là nhanh hơn thường xuyên hơn không.
Vì vậy, nếu bạn chỉ quan tâm đến các giá trị từ bảng a, bạn có thể sử dụng truy vấn này:
SELECT a.*
FROM a
WHERE EXISTS (
SELECT *
FROM b
WHERE b.col = a.col
)
Sự khác biệt có thể rất lớn nếu col không được lập chỉ mục, bởi vì db không phải tìm tất cả các bản ghi trong b có cùng giá trị bằng col, nó chỉ phải tìm cái đầu tiên. Nếu không có chỉ mục trên b.col và rất nhiều bản ghi trong quét ba bảng có thể là hậu quả. Với IN hoặc THAM GIA, đây sẽ là quét toàn bộ bảng, với EXISTS, đây sẽ chỉ là quét một phần bảng (cho đến khi tìm thấy bản ghi khớp đầu tiên).
Nếu có nhiều bản ghi trong b có cùng giá trị col, bạn cũng sẽ lãng phí rất nhiều bộ nhớ để đọc tất cả các bản ghi này vào một không gian tạm thời chỉ để thấy rằng điều kiện của bạn được thỏa mãn. Với sự tồn tại này thường có thể tránh được.
Tôi thường thấy EXISTS nhanh hơn IN ngay cả khi có chỉ mục. Nó phụ thuộc vào hệ thống cơ sở dữ liệu (trình tối ưu hóa), dữ liệu và cuối cùng không phụ thuộc vào loại chỉ mục được sử dụng.
Mỗi cơ sở dữ liệu triển khai nhưng bạn có thể đoán rằng tất cả chúng đều giải quyết các vấn đề phổ biến theo cách ít nhiều giống nhau. Nếu bạn đang sử dụng MSSQL, hãy xem kế hoạch thực hiện được tạo. Bạn có thể làm điều này bằng cách bật các kế hoạch hồ sơ và thực thi. Điều này sẽ cung cấp cho bạn một phiên bản văn bản khi bạn chạy lệnh.
Tôi không chắc bạn đang sử dụng phiên bản MSSQL nào nhưng bạn có thể lấy phiên bản đồ họa trong SQL Server 2000 trong bộ phân tích truy vấn. Tôi chắc chắn rằng chức năng này đang ẩn giấu một số vị trí trong SQL Server Studio Manager trong các phiên bản sau.
Có một cái nhìn vào kế hoạch miễn trừ. Càng xa càng tốt để tránh quét bảng trừ khi tất nhiên bảng của bạn nhỏ trong trường hợp quét bảng nhanh hơn so với sử dụng chỉ mục. Đọc về các hoạt động tham gia khác nhau mà mỗi kịch bản khác nhau tạo ra.
Trình tối ưu hóa phải đủ thông minh để cung cấp cho bạn cùng một kết quả cho các truy vấn thông thường. Kiểm tra kế hoạch thực hiện và họ sẽ cung cấp cho bạn điều tương tự. Nếu họ không, tôi thường coi THAM GIA là nhanh hơn. Tuy nhiên, tất cả các hệ thống đều khác nhau, vì vậy bạn nên lập hồ sơ mã trên hệ thống của mình để chắc chắn.