Trong các truy vấn MySQL, tại sao lại sử dụng join thay vì ở đâu?


108

Có vẻ như kết hợp hai hoặc nhiều bảng, chúng ta có thể sử dụng phép nối hoặc ở đâu. Ưu điểm của cái này hơn cái kia là gì?


2
Tùy thuộc vào cách sử dụng của bạn, nó có thể có kết quả giống nhau, nhưng với JOIN bạn có thể thực hiện các kiểu liên kết khác.
zneak

Điều này có trả lời câu hỏi của bạn không? Mệnh đề INNER JOIN ON vs WHERE
philipxy

Câu trả lời:


160

Bất kỳ truy vấn nào liên quan đến nhiều hơn một bảng đều yêu cầu một số dạng liên kết để liên kết các kết quả từ bảng "A" với bảng "B". Phương tiện truyền thống (ANSI-89) để làm điều này là:

  1. Liệt kê các bảng liên quan trong một danh sách được phân tách bằng dấu phẩy trong mệnh đề FROM
  2. Viết liên kết giữa các bảng trong mệnh đề WHERE

    SELECT *
      FROM TABLE_A a,
           TABLE_B b
     WHERE a.id = b.id

Đây là truy vấn được viết lại bằng cú pháp ANSI-92 JOIN:

SELECT *
  FROM TABLE_A a
  JOIN TABLE_B b ON b.id = a.id

Từ quan điểm hiệu suất:


Nếu được hỗ trợ (Oracle 9i +, PostgreSQL 7.2+, MySQL 3.23+, SQL Server 2000+), không có lợi ích về hiệu suất khi sử dụng cú pháp này so với cú pháp khác. Trình tối ưu hóa coi chúng là cùng một truy vấn. Nhưng các truy vấn phức tạp hơn có thể được hưởng lợi từ việc sử dụng cú pháp ANSI-92:

  • Khả năng kiểm soát thứ tự JOIN - thứ tự mà các bảng được quét
  • Khả năng áp dụng các tiêu chí bộ lọc trên một bảng trước khi tham gia

Từ quan điểm bảo trì:


Có nhiều lý do để sử dụng cú pháp ANSI-92 JOIN trên ANSI-89:

  • Dễ đọc hơn, vì tiêu chí JOIN tách biệt với mệnh đề WHERE
  • Ít có khả năng bỏ lỡ các tiêu chí THAM GIA
  • Hỗ trợ cú pháp nhất quán cho các loại JOIN ngoài INNER, giúp các truy vấn dễ sử dụng trên các cơ sở dữ liệu khác
  • Mệnh đề WHERE chỉ đóng vai trò lọc sản phẩm cacte của các bảng được nối

Từ quan điểm thiết kế:


Cú pháp ANSI-92 JOIN là mẫu, không phải phản mẫu:

  • Mục đích của truy vấn rõ ràng hơn; các cột được ứng dụng sử dụng rõ ràng
  • Nó tuân theo quy tắc mô-đun về việc sử dụng gõ nghiêm ngặt bất cứ khi nào có thể. Rõ ràng gần như tốt hơn trên toàn cầu.

Phần kết luận


Không quen thuộc và / hoặc thoải mái, tôi không thấy bất kỳ lợi ích nào khi tiếp tục sử dụng mệnh đề ANSI-89 WHERE thay vì cú pháp ANSI-92 JOIN. Một số người có thể phàn nàn rằng cú pháp ANSI-92 dài dòng hơn, nhưng đó là điều khiến nó rõ ràng. Càng rõ ràng, càng dễ hiểu và dễ bảo trì.


14
"... Bất kỳ truy vấn nào liên quan đến nhiều hơn một bảng đều yêu cầu một số dạng liên kết để liên kết các kết quả từ bảng 'A' với bảng 'B' ... Nếu không, bạn sẽ nhận được Sản phẩm Descartes và có thể bạn không muốn điều đó (những người Cartesians đó tạo ra các sản phẩm LOUSY).
Scott Smith,

8

Hầu hết mọi người có xu hướng tìm thấy cú pháp JOIN rõ ràng hơn một chút về những gì đang được nối với những gì. Ngoài ra, nó có lợi ích là một tiêu chuẩn.

Cá nhân tôi "lớn lên" trên WHEREs, nhưng tôi càng sử dụng cú pháp JOIN, tôi càng bắt đầu thấy nó rõ ràng hơn.


1
@nawfal Tôi hiểu rồi - Tôi được dạy về cú pháp kiểu cũ nhưng khi tôi đã quen với cú pháp mới, những lợi ích trở nên rõ ràng, ví dụ khó thực hiện một phép nối chéo do nhầm lẫn, rõ ràng hơn, dễ dàng hơn để xem đâu là phép nối và cái gì một bộ lọc, v.v ... Tôi đã bị mắc câu.
Cơ bản

8

Đây là những vấn đề với việc sử dụng cú pháp where (còn được gọi là liên kết ngầm):

Đầu tiên, việc kết hợp chéo ngẫu nhiên là quá dễ dàng vì các điều kiện tham gia không nằm ngay bên cạnh tên bảng. Nếu bạn có 6 bảng được nối với nhau, bạn rất dễ bỏ sót một bảng trong mệnh đề where. Bạn sẽ thấy điều này được cố định quá thường xuyên bằng cách sử dụng từ khóa riêng biệt. Đây là một cú đánh hiệu suất lớn đối với cơ sở dữ liệu. Bạn không thể nhận được một liên kết chéo ngẫu nhiên bằng cách sử dụng cú pháp liên kết rõ ràng vì nó sẽ không kiểm tra cú pháp.

Các phép nối phải và trái có vấn đề (Trong máy chủ SQl, bạn không được đảm bảo nhận được kết quả chính xác) theo cú pháp cũ trong một số cơ sở dữ liệu. Hơn nữa, chúng không được chấp nhận trong SQL Server mà tôi biết.

Nếu bạn định sử dụng phép nối chéo, thì cú pháp cũ không rõ ràng. Rõ ràng là sử dụng tiêu chuẩn ANSII hiện tại.

Người bảo trì sẽ khó hơn nhiều để xem chính xác các trường nào là một phần của phép nối hoặc thậm chí các bảng nào kết hợp với nhau theo thứ tự sử dụng cú pháp ngầm định. Điều này có nghĩa là có thể mất nhiều thời gian hơn để sửa đổi các truy vấn. Tôi đã biết rất ít người, một khi họ đã dành thời gian để cảm thấy thoải mái với cú pháp nối rõ ràng, đã từng quay lại cách cũ.

Tôi cũng nhận thấy rằng một số người sử dụng các phép nối ngầm này không thực sự hiểu cách các phép nối hoạt động và do đó nhận được kết quả không chính xác trong các truy vấn của họ.

Thành thật mà nói, bạn có sử dụng bất kỳ loại mã nào khác đã được thay thế bằng một phương pháp tốt hơn cách đây 18 năm không?


6

Các phép nối rõ ràng thể hiện ý định, để lại mệnh đề where để thực hiện việc lọc. Nó sạch hơn và nó là tiêu chuẩn, và bạn có thể làm những việc như bên trái bên ngoài hoặc bên phải bên ngoài khó làm hơn nếu chỉ ở đâu.


3

Bạn không thể sử dụng WHERE để kết hợp hai bảng. Những gì bạn có thể làm là viết:

SELECT * FROM A, B
WHERE ...

Dấu phẩy ở đây tương đương với cách viết:

SELECT *
FROM A
CROSS JOIN B
WHERE ...

Bạn sẽ viết nó? Không - bởi vì nó hoàn toàn không phải ý bạn. Bạn không muốn tham gia chéo, bạn muốn THAM GIA BÊN TRONG. Nhưng khi bạn viết dấu phẩy, bạn đang nói CROSS JOIN và điều đó thật khó hiểu.


0

Thực ra bạn thường cần cả "WHERE" và "THAM GIA".

"JOIN" được sử dụng để truy xuất dữ liệu từ hai bảng - dựa trên giá trị của một cột chung. Sau đó, nếu bạn muốn lọc thêm kết quả này, hãy sử dụng mệnh đề WHERE.

Ví dụ: "LEFT JOIN" lấy TẤT CẢ các hàng từ bảng bên trái, cộng với các hàng phù hợp từ bảng bên phải. Nhưng điều đó không lọc các bản ghi trên bất kỳ giá trị cụ thể nào hoặc trên các cột khác không phải là một phần của JOIN. Do đó, nếu bạn muốn lọc thêm kết quả này, hãy chỉ định các bộ lọc bổ sung trong mệnh đề WHERE.

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.