Det finns minst ett fall där LEFT [OUTER] JOIN är ett bättre alternativ än [INNER] JOIN . Jag pratar om att få samma resultat med OUTER istället för INNER .
Exempel (jag använder AdventureWorks 2008-databas ):
-- 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;
Resultat för den första frågan:
is_not_trusted name
-------------- ---------------------------------------------------------------
0 FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID
0 FK_SalesOrderDetail_SpecialOfferProduct_SpecialOfferIDProductID
Utförandeplaner för de två senaste frågorna:
Anmärkning 1 / Visa 1: Om vi tittar på exekveringsplanen för SELECT SalesOrderDetailID FROM View1 vi ser en FK-eliminering
eftersom FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID begränsningen är pålitlig och den har en enda kolumn. Men servern är tvingad (på grund av INNER JOIN Sales.SpecialOfferProduct ) för att läsa data från den tredje tabellen (SpecialOfferProduct) även SELECT/WHERE klausuler innehåller inga kolumner från den här tabellen och FK-begränsningen (FK_SalesOrderDetail_SpecialOfferProduct_SpecialOfferIDProductID) är (också) betrodd. Detta händer eftersom denna sista FK är flerkolumn.
Anmärkning 2 / Visa 2: Vad händer om vi vill ta bort den lästa (Scan /Seek ) på Sales.SpecialOfferProduct ? Denna andra FK är flerkolumn och för sådana fall kan SQL Server inte eliminera FK (se tidigare Conor Cunnigham blogginlägg). I det här fallet måste vi ersätta INNER JOIN Sales.SpecialOfferProduct med LEFT OUTER JOIN Sales.SpecialOfferProduct för att få FK eliminering. Båda SpecialOfferID och ProductID kolumner är NOT NULL och vi har en pålitlig FK som refererar till SpecialOfferProduct bord.