sql >> Databáze >  >> RDS >> Sqlserver

Rozdíl ve výkonu mezi levým a vnitřním spojením

Existuje alespoň jeden případ, kdy LEFT [OUTER] JOIN je lepší možnost než [INNER] JOIN . Mluvím o získání stejných výsledků pomocí OUTER místo INNER .

Příklad (používám databázi 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;

Výsledky pro první dotaz:

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

Plány provedení pro poslední dva dotazy:

Poznámka 1 / Zobrazení 1: Pokud se podíváme na plán provádění pro SELECT SalesOrderDetailID FROM View1 vidíme Vyřazení FK protože FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID omezení je důvěryhodné a má jeden sloupec. Server je však vynucený (kvůli INNER JOIN Sales.SpecialOfferProduct ) číst data ze třetí tabulky (SpecialOfferProduct), dokonce i SELECT/WHERE klauzule neobsahuje žádné sloupce z této tabulky a omezení FK (FK_SalesOrderDetail_SpecialOfferProduct_SpecialOfferIDProductID) je (také) důvěryhodné. To se děje, protože tento poslední FK je vícesloupcový.

Poznámka 2 / Zobrazení 2: Co když chceme odstranit přečtené (Scan /Seek ) na Sales.SpecialOfferProduct ? Tento druhý FK je vícesloupcový a v takových případech nemůže SQL Server odstranit FK (viz předchozí příspěvek na blogu Conora Cunnighama). V tomto případě musíme nahradit INNER JOIN Sales.SpecialOfferProduct s LEFT OUTER JOIN Sales.SpecialOfferProduct za účelem vyřazení FK. Oba SpecialOfferID a ProductID sloupce jsou NOT NULL a máme důvěryhodný FK odkazující na SpecialOfferProduct tabulka.



  1. Postgresql – dynamicky vytvořte databázi a tabulku

  2. Převod časového razítka pole datetime z mysql na php

  3. Vytvářejte soubory PDF pomocí PLSQL v Oracle

  4. Podřetězec MySQL mezi dvěma řetězci