Thứ tự tham gia có quan trọng trong SQL không?


189

Bỏ qua hiệu suất, tôi sẽ nhận được kết quả tương tự từ truy vấn A và B bên dưới chứ? C và D thì sao?

-- A
select *
from   a left join b
           on <blahblah>
       left join c
           on <blahblan>


-- B
select *
from   a left join c
           on <blahblah>
       left join b
           on <blahblan>  

-- C
select *
from   a join b
           on <blahblah>
       join c
           on <blahblan>


-- D
select *
from   a join c
           on <blahblah>
       join b
           on <blahblan>  

11
Có gì <blahblah>? bạn đang tham gia A đến B và A đến C, hay bạn đang tham gia A đến B và B đến C?
beny23

2
Xin chào Beny, mã trong câu hỏi của tôi là một sự trừu tượng. Tôi không quan tâm đến việc tham gia từ A đến B hoặc A đến C, tôi chỉ muốn biết liệu cú pháp như thế sẽ cung cấp kết quả giống hệt nhau.
Chỉ là người học

Câu trả lời:


225

Đối với INNERtham gia, không, thứ tự không quan trọng. Các truy vấn sẽ trả về kết quả tương tự, miễn là bạn thay đổi lựa chọn của mình từ SELECT *thành SELECT a.*, b.*, c.*.


Đối với ( LEFT, RIGHThoặc FULL) OUTERtham gia, vâng, thứ tự quan trọng - và ( được cập nhật ) mọi thứ phức tạp hơn nhiều.

Đầu tiên, tham gia bên ngoài không giao hoán, vì vậy a LEFT JOIN b không giống nhưb LEFT JOIN a

Các phép nối ngoài cũng không phải là kết hợp, do đó, trong các ví dụ của bạn có liên quan đến cả hai thuộc tính (giao hoán và kết hợp):

a LEFT JOIN b 
    ON b.ab_id = a.ab_id
  LEFT JOIN c
    ON c.ac_id = a.ac_id

tương đương với :

a LEFT JOIN c 
    ON c.ac_id = a.ac_id
  LEFT JOIN b
    ON b.ab_id = a.ab_id

nhưng:

a LEFT JOIN b 
    ON  b.ab_id = a.ab_id
  LEFT JOIN c
    ON  c.ac_id = a.ac_id
    AND c.bc_id = b.bc_id

không tương đương với :

a LEFT JOIN c 
    ON  c.ac_id = a.ac_id
  LEFT JOIN b
    ON  b.ab_id = a.ab_id
    AND b.bc_id = c.bc_id

Một ví dụ khác (hy vọng đơn giản hơn). Hãy nghĩ về điều này như (a LEFT JOIN b) LEFT JOIN c:

a LEFT JOIN b 
    ON b.ab_id = a.ab_id          -- AB condition
 LEFT JOIN c
    ON c.bc_id = b.bc_id          -- BC condition

Điều này tương đương với a LEFT JOIN (b LEFT JOIN c):

a LEFT JOIN  
    b LEFT JOIN c
        ON c.bc_id = b.bc_id          -- BC condition
    ON b.ab_id = a.ab_id          -- AB condition

chỉ bởi vì chúng tôi có ONđiều kiện "tốt đẹp" . Cả hai ON b.ab_id = a.ab_idc.bc_id = b.bc_idlà kiểm tra bình đẳng và không liên quanNULL so sánh.

Bạn thậm chí có thể có điều kiện với các nhà khai thác khác hoặc những phức tạp hơn như: ON a.x <= b.xhay ON a.x = 7hay ON a.x LIKE b.xhayON (a.x, a.y) = (b.x, b.y) và hai truy vấn vẫn sẽ tương đương.

Tuy nhiên, nếu bất kỳ điều nào trong số này liên quan IS NULLhoặc một chức năng có liên quan đến null như COALESCE(), ví dụ nếu điều kiện là b.ab_id IS NULL, thì hai truy vấn sẽ không tương đương.


3
Sẽ đúng hơn khi nói rằng phép nối ngoài là liên kết miễn là không có vị ngữ nào có thể được thỏa mãn bởi một hàng trong đó tất cả các cột từ một bảng là NULL, hơn là nói rằng nó có liên quan miễn là các vị từ không liên quan đến IS NULL hoặc 'một chức năng có liên quan đến null'. Người ta có thể dễ dàng tưởng tượng một vị ngữ thỏa mãn mô tả trước nhưng không phải là vị ngữ sau a.somecol > 0 OR b.someothercol > 0; associativity có thể thất bại cho điều kiện đó.
Đánh dấu Amery

Nhưng vâng, tôi nghĩ rằng về mặt kỹ thuật là đúng khi nói rằng OUTER THAM GIA có liên quan miễn là vị ngữ không thỏa mãn một trong những điều kiện tôi mô tả ở đây: stackoverflow.com/questions/20022196/iêu (điều đầu tiên cũng phá vỡ tính kết hợp đối với INNER THAM GIA, nhưng là một cách tiếp cận rẻ tiền và rõ ràng để phá vỡ nó mà có lẽ không có gì đáng nói.) Cũng đáng để chỉ ra rằng loại THAM GIA phổ biến nhất - THAM GIA khóa ngoại - không thỏa mãn một trong những điều kiện đó và do đó là tốt đẹp và kết hợp.
Đánh dấu Amery

1
@MarkAmery Cảm ơn bạn, tôi đã gặp khó khăn khi cấu trúc các câu của mình vào thời điểm đó (và tôi đã nêu lên câu trả lời của bạn;)
ypercubeᵀᴹ 17/11/13

ypercube tôi có một INNER JOINvà sau đây LEFT JOIN. Liệu nó có hoạt động như vậy trước tiên truy vấn sẽ Filtercác bản ghi trên cơ sở INNER JOINvà sau đó sẽ áp dụng LEFT JOINcho các Filteredbản ghi?
Muhammad Babar

Trên thực tế, tất cả các loại tham gia đều có liên kết, như được chỉ định bởi tiêu chuẩn SQL và theo các định nghĩa toán học về tính kết hợp, nhưng chúng không xuất hiện liên kết vì sắp xếp lại dấu ngoặc đơn yêu cầu di chuyển ONmệnh đề (nghĩa là "đặc tả tham gia") sang vị trí mới . Đây chỉ là cú pháp, mặc dù. Nếu bạn sử dụng ký hiệu đại số quan hệ (trong đó đặc tả tham gia được đặt bên dưới toán tử nối), thì tính kết hợp sẽ trở nên rõ ràng hơn. Đối số của bạn chỉ hiển thị rằng các phép nối ngoài không giao hoán , điều này là chính xác
Lukas Eder

4

đối với Joins thường xuyên, nó không. TableA join TableBsẽ tạo ra cùng một kế hoạch thực hiện như TableB join TableA(vì vậy các ví dụ C và D của bạn sẽ giống nhau)

cho trái và phải tham gia nó. TableA left Join TableBkhác với TableB left Join TableA, NHƯNG nó giống vớiTableB right Join TableA


4
Điều này chỉ giải quyết giao hoán, nhưng các ví dụ trong câu hỏi cho thấy rằng người hỏi quan tâm đến tính kết hợp. câu trả lời của ypercube giải quyết cả hai.
Đánh dấu Amery

2

Nếu bạn thử tham gia C trên một trường từ B trước khi tham gia B, nghĩa là:

SELECT A.x, A.y, A.z FROM A 
   INNER JOIN C
       on B.x = C.x
   INNER JOIN b
       on A.x = B.x

truy vấn của bạn sẽ thất bại, vì vậy trong trường hợp này thứ tự quan trọng.


Có điều này là đúng, câu trả lời đúng cần được sửa đổi.
Nir Pengas

-2

Trình tối ưu hóa Oracle chọn thứ tự tham gia của các bảng để tham gia bên trong. Trình tối ưu hóa chọn thứ tự nối các bảng chỉ trong các mệnh đề TỪ đơn giản. Bạn có thể kiểm tra tài liệu tiên tri trong trang web của họ. Và đối với bên trái, bên ngoài bên phải tham gia câu trả lời được bình chọn nhiều nhất là đúng. Trình tối ưu hóa chọn thứ tự tham gia tối ưu cũng như chỉ số tối ưu cho mỗi bảng. Thứ tự tham gia có thể ảnh hưởng đến chỉ số nào là sự lựa chọn tốt nhất. Trình tối ưu hóa có thể chọn một chỉ mục làm đường dẫn truy cập cho một bảng nếu đó là bảng bên trong, nhưng không phải là bảng bên ngoài (và không có trình độ chuyên môn nào nữa).

Trình tối ưu hóa chọn thứ tự nối các bảng chỉ trong các mệnh đề TỪ đơn giản. Hầu hết các phép nối sử dụng từ khóa THAM GIA được làm phẳng thành các phép nối đơn giản, vì vậy trình tối ưu hóa chọn thứ tự nối của chúng.

Trình tối ưu hóa không chọn thứ tự nối cho các phép nối ngoài; nó sử dụng thứ tự được chỉ định trong câu lệnh.

Khi chọn thứ tự tham gia, trình tối ưu hóa sẽ tính đến: Kích thước của mỗi bảng Các chỉ mục có sẵn trên mỗi bảng Liệu chỉ mục trên bảng có hữu ích trong một thứ tự tham gia cụ thể Số lượng hàng và trang được quét cho mỗi bảng trong mỗi bảng không tham gia đặt hàng

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.