Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Sự khác biệt về hiệu suất giữa tham gia bên trái và tham gia bên trong

Có ít nhất một trường hợp LEFT [OUTER] JOIN là một lựa chọn tốt hơn [INNER] JOIN . Tôi nói về việc đạt được kết quả tương tự bằng cách sử dụng OUTER thay vì INNER .

Ví dụ (Tôi đang sử dụng cơ sở dữ liệu AdventureWorks 2008 ):

-- Some metadata infos
SELECT  fk.is_not_trusted,  fk.name
FROM    sys.foreign_keys fk
WHERE   fk.parent_object_id=object_id('Sales.SalesOrderDetail');
GO

CREATE VIEW View1
AS 
SELECT  h.OrderDate, d.SalesOrderDetailID, o.ModifiedDate
FROM    Sales.SalesOrderDetail d
INNER JOIN Sales.SalesOrderHeader h ON d.SalesOrderID = h.SalesOrderID
INNER JOIN Sales.SpecialOfferProduct o ON d.SpecialOfferID=o.SpecialOfferID AND d.ProductID=o.ProductID;
GO

CREATE VIEW View2
AS
SELECT  h.OrderDate, d.SalesOrderDetailID, o.ModifiedDate
FROM    Sales.SalesOrderDetail d
INNER JOIN Sales.SalesOrderHeader h ON d.SalesOrderID = h.SalesOrderID
LEFT JOIN Sales.SpecialOfferProduct o ON d.SpecialOfferID=o.SpecialOfferID AND d.ProductID=o.ProductID;
GO

SELECT  SalesOrderDetailID
FROM    View1;

SELECT  SalesOrderDetailID
FROM    View2;

Kết quả cho truy vấn đầu tiên:

is_not_trusted name
-------------- ---------------------------------------------------------------
0              FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID
0              FK_SalesOrderDetail_SpecialOfferProduct_SpecialOfferIDProductID

Kế hoạch thực thi cho hai truy vấn cuối cùng:

Lưu ý 1 / Chế độ xem 1: Nếu chúng ta xem xét kế hoạch thực thi cho SELECT SalesOrderDetailID FROM View1 chúng tôi thấy Loại bỏ FK bởi vì FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID ràng buộc được tin cậy và nó có một cột duy nhất. Tuy nhiên, máy chủ bị ép buộc (vì INNER JOIN Sales.SpecialOfferProduct ) để đọc dữ liệu từ bảng thứ ba (SpecialOfferProduct) ngay cả SELECT/WHERE mệnh đề không chứa bất kỳ cột nào từ bảng này và ràng buộc FK (FK_SalesOrderDetail_SpecialOfferProduct_SpecialOfferIDProductID) (cũng) được tin cậy. Điều này xảy ra vì FK cuối cùng này là nhiều cột.

Lưu ý 2 / Chế độ xem 2: Điều gì xảy ra nếu chúng ta muốn xóa nội dung đã đọc (Scan / Seek ) trên Sales.SpecialOfferProduct ? FK thứ hai này là đa cột và trong những trường hợp như vậy, Máy chủ SQL không thể loại bỏ FK (xem bài đăng trên blog Conor Cunnigham trước đó). Trong trường hợp này, chúng tôi cần thay thế INNER JOIN Sales.SpecialOfferProduct với LEFT OUTER JOIN Sales.SpecialOfferProduct để loại bỏ FK. Cả SpecialOfferIDProductID các cột NOT NULL và chúng tôi có tham chiếu FK đáng tin cậy SpecialOfferProduct bảng.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Sử dụng SQL 2005 Pivot

  2. Gợi ý về SQL SERVER 2008 JOIN

  3. Phương pháp nhanh nhất để chèn, cập nhật, lựa chọn SQL Server

  4. Giới thiệu tính năng mới - Spotlight Cloud Replication

  5. Chọn ký tự cyrillic trong SQL