Cái nào tốt hơn: nhiều điều kiện tham gia hay nhiều điều kiện ở đâu?


13

Tôi đang cố gắng so sánh hai truy vấn:

Truy vấn 1:

SELECT a,b,c,d,e
FROM tableA
LEFT JOIN tableB
ON tableA.a=tableB.a
WHERE tableA.b=tableB.b AND tableA.c=tableB.c  AND tableA.d=tableB.d  AND tableA.e=tableB.e 

Truy vấn 2:

SELECT a,b,c,d,e
FROM tableA
LEFT JOIN tableB
ON tableA.a=tableB.a AND tableA.b=tableB.b AND tableA.c=tableB.c  AND tableA.d=tableB.d  
WHERE tableA.e=tableB.e 

Tôi có đúng không khi nói rằng hai truy vấn này cho kết quả giống nhau?

Hơn nữa, có đúng không khi nói rằng truy vấn đầu tiên xây dựng một bảng lớn hơn để thực hiện một WHEREđiều kiện lớn hơn ; trong khi đó trường hợp thứ hai chúng ta có một bảng được xây dựng nhỏ hơn để WHEREáp dụng đơn giản .

Giả sử kết quả là như nhau, truy vấn nào nên được ưu tiên? Có một vấn đề hiệu suất rõ ràng?


3
Không, bạn không đúng khi nói điều đó. Nó sẽ là nếu đó là một INNER JOIN, nhưng với LEFT JOINđiều này sẽ trả lại kết quả khác nhau. Về cơ bản, các điều kiện mà bạn đã thêm vào WHEREtruy vấn thứ hai là chuyển đổi JOINtrên mộtINNER JOIN
Lamak

À được rồi Tôi làm theo những gì bạn nói. Nếu tôi chỉnh sửa để INNER JOINlàm cho câu hỏi của tôi về hiệu suất vẫn còn hiệu lực?
Geoff

4
Đối với INNER THAM GIA, không có sự khác biệt về hiệu suất. Điều đó nói rằng, để dễ đọc và thể hiện đúng ý định, bạn nên sử dụng tiêu chí tham gia trong ONvà tiêu chí lọc trong WHERE.
Aaron Bertrand

@ypercube đúng rồi, mình bỏ qua điều kiện đó.
Lamak

Câu trả lời:


10

Nếu chúng tôi xem xét rằng bạn sử dụng INNER JOINthay vìLEFT JOIN (dường như là mục đích của bạn), hai truy vấn này tương đương về mặt chức năng. Trình tối ưu hóa truy vấn sẽ xem xét và đánh giá các tiêu chí trong WHEREmệnh đề và mệnh đề của bạn FROMvà xem xét tất cả các yếu tố này khi xây dựng kế hoạch truy vấn để đạt được kế hoạch thực hiện hiệu quả nhất. Nếu chúng ta thực hiện EXPLAINtrên cả hai câu lệnh, chúng ta sẽ nhận được cùng một kết quả:

Truy vấn 1 :

EXPLAIN
SELECT 
  tableA.ColA
  ,tableA.ColB
  ,tableA.ColC
  ,tableA.ColD
  ,tableA.ColE
FROM tableA
  JOIN tableB ON tableA.ColA=tableB.ColA
WHERE 
  tableA.ColB=tableB.ColB 
  AND tableA.ColC=tableB.ColC 
  AND tableA.ColD=tableB.ColD  
  AND tableA.ColE=tableB.ColE

[Các kết quả] :

| ID | SELECT_TYPE |  TABLE | TYPE | POSSIBLE_KEYS |    KEY | KEY_LEN |    REF | ROWS |                          EXTRA |
------------------------------------------------------------------------------------------------------------------------
|  1 |      SIMPLE | tableA |  ALL |        (null) | (null) |  (null) | (null) |    1 |                                |
|  1 |      SIMPLE | tableB |  ALL |        (null) | (null) |  (null) | (null) |    1 | Using where; Using join buffer |

Truy vấn 2 :

EXPLAIN
SELECT 
  tableA.ColA
  ,tableA.ColB
  ,tableA.ColC
  ,tableA.ColD
  ,tableA.ColE
FROM tableA
  JOIN tableB ON tableA.ColA=tableB.ColA
  AND tableA.ColB=tableB.ColB 
  AND tableA.ColC=tableB.ColC 
  AND tableA.ColD=tableB.ColD  
WHERE
  tableA.ColE=tableB.ColE

[Các kết quả] :

| ID | SELECT_TYPE |  TABLE | TYPE | POSSIBLE_KEYS |    KEY | KEY_LEN |    REF | ROWS |                          EXTRA |
------------------------------------------------------------------------------------------------------------------------
|  1 |      SIMPLE | tableA |  ALL |        (null) | (null) |  (null) | (null) |    1 |                                |
|  1 |      SIMPLE | tableB |  ALL |        (null) | (null) |  (null) | (null) |    1 | Using where; Using join buffer |

Bạn có thể xem lại chi tiết đầy đủ với các liên kết sau. Tôi cũng đã tạo một ví dụ SQL 2008 để bạn có thể so sánh cách hai công cụ hoạt động (giống nhau):

Ví dụ truy vấn MySQL

Ví dụ truy vấn SQL 2008 (Đảm bảo bạn 'Xem Kế hoạch thực hiện' cho cả hai kết quả)


Cảm ơn bạn cho giải pháp chi tiết của bạn. Tôi đã thử INNER JOINthay vì LEFT JOINvà tôi nhận được cùng một đầu ra trong một phần mười thời gian. Tôi nghĩ rằng tôi biết tại sao tôi nhận được cùng một đầu ra, nhưng tại sao một INNER JOINhiệu suất tốt hơn?
Geoff

4
LEFT JOINlà một phép nối ngoài, nó không thể hạn chế tập dữ liệu ở phía hoàn trả đầy đủ của tập và sẽ cố gắng truy xuất tất cả các hàng từ bảng đó (trong trường hợp này là TableA). Nếu bạn sử dụng INNER JOIN, nó có thể tận dụng các tiêu chí đó trên cả hai bảng và hạn chế tập dữ liệu, do đó mang lại lợi nhuận nhanh hơn.
Mike Fal
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.