Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Różnica wydajności między sprzężeniem lewym a sprzężeniem wewnętrznym

Istnieje co najmniej jeden przypadek, w którym LEFT [OUTER] JOIN jest lepszą opcją niż [INNER] JOIN . Mówię o uzyskaniu tych samych wyników przy użyciu OUTER zamiast INNER .

Przykład (używam bazy danych 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;

Wyniki dla pierwszego zapytania:

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

Plany wykonania dla dwóch ostatnich zapytań:

Uwaga 1 / Widok 1: Jeśli spojrzymy na plan wykonania dla SELECT SalesOrderDetailID FROM View1 widzimy eliminacja FK ponieważ FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID ograniczenie jest zaufane i ma jedną kolumnę. Ale serwer jest wymuszony (z powodu INNER JOIN Sales.SpecialOfferProduct ) aby odczytać dane z trzeciej tabeli (SpecialOfferProduct) nawet SELECT/WHERE klauzule nie zawierają żadnych kolumn z tej tabeli, a ograniczenie FK (FK_SalesOrderDetail_SpecialOfferProduct_SpecialOfferIDProductID) jest (również) zaufane. Dzieje się tak, ponieważ ten ostatni FK jest wielokolumnowy.

Uwaga 2 / Widok 2: Co jeśli chcemy usunąć odczytane (Scan /Seek ) na Sales.SpecialOfferProduct ? Ten drugi plik FK jest wielokolumnowy iw takich przypadkach SQL Server nie może go wyeliminować (patrz poprzedni wpis na blogu Conora Cunnighama). W takim przypadku musimy zastąpić INNER JOIN Sales.SpecialOfferProduct z LEFT OUTER JOIN Sales.SpecialOfferProduct aby uzyskać eliminację FK. Oba SpecialOfferID i ProductID kolumny są NOT NULL i mamy zaufany FK odwołujący się do SpecialOfferProduct tabela.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Podzapytanie v/s wewnętrzne sprzężenie w serwerze sql

  2. Populacja skryptów ładowania danych projektu bazy danych Visual Studio z istniejących danych

  3. Jak mogę wyczyścić SSISDB?

  4. Przechowywanie komunikatu raiserror z SqlServer w C#

  5. Klient z adresem IP nie ma dostępu do bazy danych Azure SQL serwera