Der er mindst ét tilfælde, hvor LEFT [OUTER] JOIN er en bedre mulighed end [INNER] JOIN . Jeg taler om at få de samme resultater ved at bruge OUTER i stedet for INNER .
Eksempel (jeg bruger AdventureWorks 2008-database ):
-- 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;
Resultater for den første forespørgsel:
is_not_trusted name
-------------- ---------------------------------------------------------------
0 FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID
0 FK_SalesOrderDetail_SpecialOfferProduct_SpecialOfferIDProductID
Udførelsesplaner for de sidste to forespørgsler:
Bemærkning 1 / Visning 1: Hvis vi ser på eksekveringsplanen for SELECT SalesOrderDetailID FROM View1 vi ser en FK-eliminering
fordi FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID begrænsning er tillid til, og den har en enkelt kolonne. Men serveren er tvunget (på grund af INNER JOIN Sales.SpecialOfferProduct ) for at læse data fra den tredje tabel (SpecialOfferProduct) selv SELECT/WHERE klausuler indeholder ingen kolonner fra denne tabel, og FK-begrænsningen (FK_SalesOrderDetail_SpecialOfferProduct_SpecialOfferIDProductID) er (også) tillid til. Dette sker, fordi denne sidste FK er multikolonne.
Bemærkning 2 / Visning 2: Hvad hvis vi vil fjerne læst (Scan /Seek ) på Sales.SpecialOfferProduct ? Denne anden FK er multikolonne, og i sådanne tilfælde kan SQL Server ikke eliminere FK'en (se tidligere Conor Cunnigham blogindlæg). I dette tilfælde skal vi erstatte INNER JOIN Sales.SpecialOfferProduct med LEFT OUTER JOIN Sales.SpecialOfferProduct for at få FK-eliminering. Begge SpecialOfferID og ProductID kolonner er NOT NULL og vi har en betroet FK, der henviser til SpecialOfferProduct tabel.