Hiệu suất SQL THAM GIA VÀ IN?


164

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 thực sự đang tìm kiếm một bài viết khác mà tôi đã sử dụng khi tôi nghiên cứu một thứ tương tự trước đây và tình cờ tìm thấy một bài viết đó
AdaTheDev

Xin lỗi vì có thể bị lừa ... đã không tìm thấy câu hỏi đó khi tôi đang tìm kiếm
Polaris878

Câu trả lời:


196

Nói chung, INJOINlà 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.collà 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à UNIQUEvà đượ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ì INnhanh hơn JOINtrên DISTINCT.

Xem bài viết này trong blog của tôi để biết chi tiết hiệu suất:


Vâng, điều hợp lý là họ sẽ thực hiện tương tự nếu cột tham gia là duy nhất (đó là trong trường hợp của tôi)
Polaris878

1
Trên một lưu ý tương tự, tôi nên sử dụng IN (CHỌN DISTINCT ...) hay đơn giản là IN (CHỌN ...)?
moo

8
@ orlandu63: INngụ ý 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 RDBMSsẽ cư xử như thế nào .
Quassnoi

>> IN và THAM GIA là các truy vấn khác nhau có thể mang lại kết quả khác nhau. Bạn có thể giải thích tại sao nó sẽ tạo ra kết quả khác nhau trong trường hợp này ngay cả khi b.col không phải là duy nhất?
Abhijeet



6

Đ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


Tôi cũng đã nghĩ vậy ... vì có vẻ như THAM GIA là một trường hợp phổ biến hơn và nhiều khả năng sẽ được tối ưu hóa
Polaris878

4

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.


4

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.


3
Trên MSSql, thực tế tồn tại tốt hơn IN dường như không đúng. Để biết thêm thông tin: notifyextends.com/2009/06/16/in-vs-join-vs-exists Trên đây bạn có thể đọc rằng: "Nhiều người nghĩ rằng EXISTS hiệu quả hơn IN, bởi vì EXISTS chỉ trả về một hàng. Đây là không đúng với SQL Server. Như chúng ta có thể thấy từ các ví dụ trên, EXISTS và IN tạo ra các kế hoạch giống hệt nhau. Điều này là do EXISTS linh hoạt hơn IN. IN luôn có thể được viết lại thành EXISTS (sử dụng điều kiện WHERE đơn giản với đẳng thức ) nhưng không phải ngược lại. "
Micaël Félix

3

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.


1

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.


5
Nên làm? Có lẽ. Phải không? Không. Xem bài viết của tôi.
cletus
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.