2009-07-07 66 views
6

Tôi có lẽ nên biết điều này ngay bây giờ, nhưng điều gì sẽ xảy ra nếu có sự khác biệt giữa hai câu dưới đây?SQL - Sự khác nhau giữa các kết nối này?

Các lồng nhau tham gia:

SELECT 
    t1.* 
FROM 
    table1 t1 
    INNER JOIN table2 t2 
     LEFT JOIN table3 t3 ON t3.table3_ID = t2.table2_ID 
    ON t2.table2_ID = t1.table1_ID 

Các truyền thống hơn join:

SELECT 
    t1.* 
FROM 
    table1 t1 
    INNER JOIN table2 t2 ON t2.table2_ID = t1.table1_ID 
    LEFT JOIN table3 t3 ON t3.table3_ID = t2.table2_ID 
+0

Họ có đưa ra kết quả tương tự khi bạn thực thi chúng không? –

+0

+1 để làm cho tôi đi "Hm ..." – Tomalak

+0

Đó là một heck của rất nhiều dễ dàng hơn để hiểu thứ hai hơn so với cái đầu tiên - ngay cả khi bạn đặt (parens) xung quanh LOJ trong lần đầu tiên. Nhìn về phía trước để bỏ phiếu cho một câu trả lời tốt về điều này. –

Trả lời

5

Vâng, đó là thứ tự của các hoạt động ..

SELECT 
    t1.* 
FROM 
    table1 t1 
    INNER JOIN table2 t2 
     LEFT JOIN table3 t3 ON t3.table3_ID = t2.table2_ID 
    ON t2.table2_ID = t1.table1_ID 

có thể được viết lại như sau:

SELECT 
    t1.* 
FROM 
     table1 t1              -- inner join t1 
    INNER JOIN 
     (table2 t2 LEFT JOIN table3 t3 ON t3.table3_ID = t2.table2_ID) -- with this 
    ON t2.table2_ID = t1.table1_ID          -- on this condition 

vì vậy, về cơ bản, trước tiên bạn LEFT JOIN t2 với t3, căn cứ vào điều kiện tham gia: table3_ID = table2_ID, sau đó bạn INNER JOIN t1 với t2 trên table2_ID = table1_ID.

Trong ví dụ thứ hai, bạn đầu tiên INNER JOIN t1 với t2, và sau đó LEFT JOIN kết nối bên trong kết quả với bảng t3 trên bảng điều kiện2_ID = table1_ID.

SELECT 
    t1.* 
FROM 
    table1 t1 
    INNER JOIN table2 t2 ON t2.table2_ID = t1.table1_ID 
    LEFT JOIN table3 t3 ON t3.table3_ID = t2.table2_ID   

có thể được viết lại như sau:

SELECT 
    t1.* 
FROM 
     (table1 t1 INNER JOIN table2 t2 ON t2.table2_ID = t1.table1_ID) -- first inner join 
    LEFT JOIN               -- then left join 
     table3 t3 ON t3.table3_ID = t2.table2_ID      -- the result with this 

EDIT

Tôi xin lỗi. Nhận xét đầu tiên của tôi là sai. Hai truy vấn sẽ tạo ra kết quả tương tự nhưng có thể có sự khác biệt về hiệu suất vì truy vấn đầu tiên có thể hoạt động chậm hơn truy vấn thứ hai trong một số trường hợp (khi bảng 1 chỉ chứa một tập con của các phần tử trong bảng 2). được thực thi đầu tiên - và chỉ sau đó được giao với bảng 1. Trái ngược với truy vấn thứ hai cho phép trình tối ưu hóa truy vấn thực hiện công việc của nó.

+1

Rõ ràng thứ tự của các hoạt động là khác nhau, nhưng có sự khác biệt thực tế nào (hiệu suất, kết quả, bất kỳ thứ gì) không? –

+1

Vui lòng cung cấp ví dụ về dữ liệu trong đó các truy vấn sẽ trả lại các kết quả khác nhau. Tôi đã không thể tạo ra bất kỳ. –

+0

Ok, cảm ơn những suy nghĩ về những người này. Nó khá giống như tôi nghĩ lúc đó. Kết quả sẽ giống nhau, nhưng các truy vấn có thể hoạt động khác nhau. Tôi nghĩ rằng để dễ sử dụng, tôi sẽ thay đổi truy vấn cũ (lồng nhau) để sử dụng cú pháp truyền thống hơn. – TehOne

4

Ví dụ cụ thể của bạn, tôi không nghĩ rằng có nên có bất kỳ sự khác biệt trong kế hoạch truy vấn được tạo ra, nhưng chắc chắn có sự khác biệt về khả năng đọc. Ví dụ thứ 2 của bạn là MUCH dễ theo dõi hơn.

Nếu bạn đảo ngược các loại tham gia trong ví dụ này, bạn có thể kết thúc với nhiều kết quả khác nhau.

SELECT t1.* 
FROM table1 t1 
    LEFT JOIN table2 t2 ON t2.table2_ID = t1.table1_ID 
    INNER JOIN table3 t3 ON t3.table3_ID = t2.table2_ID 

-- may not produce the same results as... 

SELECT t1.* 
FROM table1 t1 
    LEFT JOIN table2 t2 
     INNER JOIN table3 t3 ON t3.table3_ID = t2.table2_ID 
    ON t2.table2_ID = t1.table1_ID 

Căn cứ vào thực tế là thứ tự của các kết nối CÓ vấn đề trong nhiều trường hợp - hãy suy nghĩ cẩn thận về cách bạn viết cú pháp nối. Nếu bạn thấy rằng ví dụ thứ 2 là những gì bạn đang thực sự cố gắng để đạt được, tôi muốn xem xét việc viết lại các truy vấn để bạn có thể đặt trọng tâm nhiều hơn vào thứ tự của tham gia của bạn ...

SELECT t1.* 
FROM table2 t2 
     INNER JOIN table3 t3 ON t3.table3_ID = t2.table2_ID 
     RIGHT JOIN table1 t1 ON t2.table2_ID = t1.table1_ID 
2

Cách tốt nhất để xem điều gì khác biệt trong hai truy vấn này là so sánh Kế hoạch truy vấn cho cả hai truy vấn này.

Không có sự khác biệt trong tập kết quả cho các NẾU luôn có các hàng trong bảng 3 cho một hàng nhất định trong bảng 2.

Tôi đã thử nó trên cơ sở dữ liệu của mình và sự khác biệt trong kế hoạch truy vấn là 1. Đối với truy vấn đầu tiên, trình tối ưu hóa đã chọn tham gia vào bảng 2 và bảng 3 trước. 2.Đối với truy vấn thứ hai, trình tối ưu hóa đã chọn tham gia table1 và table2 trước tiên.

+0

Đối với tôi, kế hoạch thực hiện cho các truy vấn thực sự của tôi giống hệt nhau. – TehOne

0

Bạn sẽ thấy không có sự khác biệt nào giữa hai truy vấn, miễn là trình tối ưu hóa DBMS của bạn được cập nhật. Điều đó, tuy nhiên, ngay cả đối với các nền tảng sắt lớn, chi phí cao, không phải là một giả định tôi sẽ tự tin khi thực hiện, vì vậy tôi sẽ không ngạc nhiên khi phát hiện ra rằng các kế hoạch truy vấn (và do đó thời gian thực hiện) thay đổi.

Các vấn đề liên quan