Đặt một điều kiện liên quan đến một bảng trong THAM GIA là tốt hơn?


8

Tôi đã thấy điều này rất nhiều khi mọi người đặt điều kiện liên quan đến bảng vào mệnh đề THAM GIA. Xem ví dụ này,

SELECT i.Name
  FROM sys.TABLES AS tbl
  INNER JOIN sys.indexes AS i
    ON (i.index_id > 0 AND i.is_hypothetical = 0) 
    AND (i.object_id = tbl.object_id)
  WHERE (i.is_unique = 1 AND i.is_disabled = 0) 
    AND (tbl.Name = 'Warehouse')


SELECT i.Name
  FROM sys.TABLES AS tbl
  INNER JOIN sys.indexes AS i
    ON (i.object_id = tbl.object_id)
  WHERE (i.index_id > 0 AND i.is_hypothetical = 0) 
  AND (i.is_unique = 1 AND i.is_disabled = 0) 
  AND (tbl.Name = 'Warehouse')

Truy vấn là như nhau nhưng sự khác biệt là, cái đầu tiên được sử dụng (i.index_id > 0 AND i.is_hypothetical = 0)trong mệnh đề THAM GIA trong đó cái thứ hai sử dụng tương tự trong mệnh đề WHERE. Đây có phải là tác động đến truy vấn hoặc hiệu suất?


4
Cách duy nhất để biết chắc chắn là có được kế hoạch thực hiện cho cả hai truy vấn. Tôi tưởng tượng họ sẽ giống nhau. Đối với một trong INNER JOINnhững truy vấn tương đương. Đối với OUTER JOINviệc đặt điều kiện vào điều kiện tham gia thay vì WHEREsẽ thay đổi kết quả của bạn, vì vậy hãy cẩn thận.
JNK

Câu trả lời:


10

Như JNK đã nói, đối với một INNER JOIN, những điều này sẽ giống nhau. Bạn có thể chứng minh điều đó bằng cách so sánh các kế hoạch thực hiện (không bận tâm với ước tính ). Trong trường hợp này, chúng giống hệt nhau ( bấm vào để phóng to ):

nhập mô tả hình ảnh ở đây

Cá nhân, tôi muốn giữ các điều kiện tham gia và các điều kiện lọc riêng biệt. Tham gia điều kiện đi trong ONmệnh đề và điều kiện lọc đi trong WHEREmệnh đề. Đây là một trong những lợi ích chính của việc có INNER JOINcú pháp rõ ràng ở vị trí đầu tiên, giúp giảm rủi ro trả lại quá nhiều hàng vì không đủ (hoặc thậm chí không có ) tiêu chí tham gia vốn có trong các tham gia kiểu cũ (nơi lọc và tham gia tiêu chí được ném cùng nhau) - xem bài đăng trên blog này để biết thêm chi tiết .

JNK cũng đúng mặc dù bạn cần cẩn thận khi nói về OUTER JOIN. Một ví dụ đơn giản:

CREATE TABLE dbo.a(id INT);

CREATE TABLE dbo.b(id INT, name SYSNAME);

INSERT dbo.a(id) VALUES(1),(2),(3);

INSERT dbo.b(id) VALUES(2,N'a'),(3,N'b');

SELECT a.id, b.name 
  FROM dbo.a 
  LEFT OUTER JOIN dbo.b
  ON a.id = b.id 
  AND b.name LIKE N'b%';

SELECT a.id, b.name
  FROM dbo.a 
  LEFT OUTER JOIN dbo.b
  ON a.id = b.id 
  WHERE b.name LIKE N'b%';
--^^^^^ only difference

DROP TABLE dbo.a, dbo.b;

Các kết quả:

id    name
----  ----
1     NULL
2     NULL
3     b

id    name
----  ----
3     b

Như bạn có thể nhìn thấy từ các kết quả, truy vấn đầu tiên vẫn trả về tất cả ba hàng từ a(như bạn mong chờ), tuy nhiên các truy vấn thứ hai biến OUTER JOINthành một INNER JOIN, và chỉ trả về các hàng từ avới một trận đấu từ btrên tất cả các điều kiện. Bạn có thể muốn một hành vi này hoặc hành vi khác, vì vậy cả hai hành vi này đều "tệ hơn" hoặc "sai", điều quan trọng là phải hiểu các chức năng khác nhau để bạn biết viết truy vấn để nhận được kết quả mà bạn đang theo dõi.

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.