2009-06-15 23 views
7

Tôi có hai bảng:Việc lọc hoặc tham gia diễn ra đầu tiên trong T-SQL?

Customers(Id, Name, TownId) T 
Towns(Id, Name) 

Tôi có một câu lệnh SQL như thế này:

SELECT * 
FROM Customers 
INNER JOIN Towns ON Towns.Id = Customers.TownId 
WHERE Customers.Id > 5 

Điều gì sẽ xảy ra đầu tiên?
Nó có lọc bảng Customers và sau đó tham gia các bản ghi đã chọn với bảng Towns không?
Nó có tham gia tất cả Customers với Towns và sau đó lọc không? Hay là bạn không thể nói?

Trả lời

15

Trình tối ưu hóa sẽ làm bất kỳ điều gì mà nó cho là nhanh nhất.

Bạn có thể bắt buộc các hành vi nhất định với các gợi ý tham gia hoặc khuyến khích một số hành vi nhất định với thống kê và chỉ mục. Tuy nhiên, tốt nhất là nên tin tưởng vào Trình tối ưu hóa.

Nếu bạn muốn giải thích chi tiết về cách truy vấn được thực thi, hãy xem execution plan.

+3

Các kỹ thuật phổ biến để "buộc" một QEP cụ thể gần như tất cả các nhà cung cấp phụ thuộc ... có hiệu quả đạt được nhà cung cấp-lock-in. Cẩn thận với Axe đó, Eugene. – corlettk

+0

+1 cho Pink Floyd. :-) – GuyBehindtheGuy

0

Trong thuật ngữ bố cục, bộ lọc sẽ xảy ra trước khi tham gia, do đó bạn sẽ không tham gia toàn bộ cả hai bảng trước khi lọc.

Tùy thuộc vào bộ công cụ bạn đang sử dụng, bạn sẽ tìm thấy tùy chọn để hiển thị kế hoạch thực hiện truy vấn, điều này sẽ giúp bạn xem thứ tự thực hiện và chi phí của từng giai đoạn.

1

Nói chung, việc tham gia diễn ra trước tiên. Xem xét:

 
t1.id t1.foo  t2.id t2.bar t2.t1_id 
-------------  ------------------------ 
    1 'abc'   1 '123'   1 
    2 'def'   2 '456'   1 
    3 'ghi'   3 '789'   2 
    4 'jkl'   4 '0'  NULL 

truy vấn này:

SELECT 
    t1.foo, 
    t2.bar 
FROM 
    t1 
    LEFT JOIN t2 ON t1.id = t2.t1_id 
WHERE 
    t2.somevalue IS NOT NULL 

sẽ mang lại:

 
foo  bar 
------------- 
'abc' '123' 
'abc' '456' 
'def' '789' 

trong khi, khi bạn kéo các bộ lọc vào điều kiện join, lọc xảy ra tại gia cũng như:

SELECT 
    t1.foo, 
    t2.bar 
FROM 
    t1 
    LEFT JOIN t2 ON t1.id = t2.t1_id AND t2.somevalue IS NOT NULL 

sẽ mang lại:

 
foo  bar 
------------- 
'abc' '123' 
'abc' '456' 
'def' '789' 
'ghi' NULL 
'jkl' NULL 

Truy vấn càng phức tạp, càng dễ nói bản ghi nào được lọc theo kế hoạch thực hiện trước khi các bảng được nối và sau đó.

+0

nó không chính xác câu trả lời cho câu hỏi của tôi .. trong ví dụ MY, bạn có thể đảm bảo rằng việc tham gia sẽ luôn luôn xảy ra đầu tiên? – agnieszka

+0

Trong ví dụ * * của bạn, nó không tạo ra sự khác biệt nào cả, bởi vì bạn sử dụng một phép nối bên trong. Lọc đầu tiên - tham gia sau, hoặc theo cách khác xung quanh, sẽ không có kết quả khác nhau bất kể bạn làm gì. Các trường hợp cạnh là với các kết nối bên ngoài. – Tomalak

+0

nó làm cho không có sự khác biệt trong kết quả, nhưng nó làm cho sự khác biệt về hiệu quả.anyway, nó không quan trọng, tôi chỉ muốn biết những gì xảy ra đầu tiên, ngay cả khi kết quả trả về là cùng một máy chủ SQL – agnieszka

0

Khi truy vấn được thực hiện dưới dạng hợp nhất, việc lọc và nối diễn ra đồng thời.

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