Es gibt mindestens einen Fall, in dem LEFT [OUTER] JOIN
ist eine bessere Option als [INNER] JOIN
. Ich spreche davon, dieselben Ergebnisse mit OUTER
zu erhalten statt INNER
.
Beispiel (Ich verwende AdventureWorks 2008-Datenbank ):
-- 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;
Ergebnisse für die erste Abfrage:
is_not_trusted name
-------------- ---------------------------------------------------------------
0 FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID
0 FK_SalesOrderDetail_SpecialOfferProduct_SpecialOfferIDProductID
Ausführungspläne für die letzten beiden Abfragen:
Anmerkung 1 / Ansicht 1: Betrachten wir den Ausführungsplan für SELECT SalesOrderDetailID FROM View1
wir sehen einen FK-Eliminierung
weil die FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID
Einschränkung ist vertrauenswürdig und hat eine einzelne Spalte. Aber der Server wird gezwungen (wegen INNER JOIN Sales.SpecialOfferProduct
). ), um Daten aus der dritten Tabelle (SpecialOfferProduct) zu lesen, sogar das SELECT/WHERE
-Klauseln enthält keine Spalten aus dieser Tabelle und der FK-Einschränkung (FK_SalesOrderDetail_SpecialOfferProduct_SpecialOfferIDProductID) wird (ebenfalls) vertraut. Dies geschieht, weil dieser letzte FK mehrspaltig ist.
Anmerkung 2 / Ansicht 2: Was ist, wenn wir die gelesene Datei entfernen möchten (Scan
/Seek
) auf Sales.SpecialOfferProduct
? Dieser zweite FK ist mehrspaltig und in solchen Fällen kann der SQL Server den FK nicht eliminieren (siehe vorherigen Blogbeitrag von Conor Cunnigham). In diesem Fall müssen wir das INNER JOIN Sales.SpecialOfferProduct
ersetzen mit LEFT OUTER JOIN Sales.SpecialOfferProduct
um die FK-Eliminierung zu erreichen. Sowohl SpecialOfferID
und ProductID
Spalten sind NOT NULL
und wir haben einen vertrauenswürdigen FK, der auf SpecialOfferProduct
verweist Tabelle.