sql >> Database >  >> RDS >> Sqlserver

Prestatieverschil tussen left join en inner join

Er is ten minste één geval waarin LEFT [OUTER] JOIN is een betere optie dan [INNER] JOIN . Ik heb het over het verkrijgen van dezelfde resultaten met OUTER in plaats van INNER .

Voorbeeld (ik gebruik 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;

Resultaten voor de eerste zoekopdracht:

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

Uitvoeringsplannen voor de laatste twee query's:

Opmerking 1 / Weergave 1: Als we kijken naar het uitvoeringsplan voor SELECT SalesOrderDetailID FROM View1 we zien een FK-eliminatie omdat de FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID beperking is vertrouwd en heeft een enkele kolom. Maar de server wordt geforceerd (vanwege INNER JOIN Sales.SpecialOfferProduct ) om gegevens uit de derde tabel (SpecialOfferProduct) te lezen, zelfs de SELECT/WHERE clausules bevat geen kolommen uit deze tabel en de FK-beperking (FK_SalesOrderDetail_SpecialOfferProduct_SpecialOfferIDProductID) is (ook) vertrouwd. Dit gebeurt omdat deze laatste FK uit meerdere kolommen bestaat.

Opmerking 2 / Weergave 2: Wat als we de gelezen (Scan /Seek ) op het Sales.SpecialOfferProduct ? Deze tweede FK is multicolumn en in dergelijke gevallen kan de SQL Server de FK niet elimineren (zie vorige Conor Cunnigham blogpost). In dit geval moeten we de INNER JOIN Sales.SpecialOfferProduct . vervangen met LEFT OUTER JOIN Sales.SpecialOfferProduct om FK eliminatie te krijgen. Beide SpecialOfferID en ProductID kolommen zijn NOT NULL en we hebben een vertrouwde FK die verwijst naar SpecialOfferProduct tafel.



  1. Hoe importeer je meer dan 100.000 records in een mysql-database?

  2. Slaapstand @Version waardoor de beperking van de externe sleutel van de database mislukt

  3. Mysql-tekenreeks splitsen

  4. Doe wiskunde in MySQL vanuit SELECT