Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Perbedaan kinerja antara gabungan kiri dan gabungan dalam

Setidaknya ada satu kasus di mana LEFT [OUTER] JOIN adalah pilihan yang lebih baik daripada [INNER] JOIN . Saya berbicara tentang mendapatkan hasil yang sama menggunakan OUTER bukannya INNER .

Contoh (Saya menggunakan database 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;

Hasil untuk kueri pertama:

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

Rencana eksekusi untuk dua kueri terakhir:

Catatan 1 / Tampilan 1: Jika kita melihat rencana eksekusi untuk SELECT SalesOrderDetailID FROM View1 kami melihat Penghapusan FK karena FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID kendala dipercaya dan memiliki satu kolom. Tapi, server dipaksa (karena INNER JOIN Sales.SpecialOfferProduct ) untuk membaca data dari tabel ketiga (SpecialOfferProduct) bahkan SELECT/WHERE klausa tidak berisi kolom apa pun dari tabel ini dan batasan FK (FK_SalesOrderDetail_SpecialOfferProduct_SpecialOfferIDProductID) (juga) tepercaya. Hal ini terjadi karena FK terakhir ini multikolom.

Catatan 2 / Tampilan 2: Bagaimana jika kita ingin menghapus tanda baca (Scan /Seek ) pada Sales.SpecialOfferProduct ? FK kedua ini multicolumn dan untuk kasus seperti itu SQL Server tidak dapat menghilangkan FK (lihat posting blog Conor Cunnigham sebelumnya). Dalam hal ini kita perlu mengganti INNER JOIN Sales.SpecialOfferProduct dengan LEFT OUTER JOIN Sales.SpecialOfferProduct untuk mendapatkan eliminasi FK. Keduanya SpecialOfferID dan ProductID kolom adalah NOT NULL dan kami memiliki referensi FK tepercaya SpecialOfferProduct tabel.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana cara mendapatkan tanggal pertama dan terakhir tahun ini?

  2. Baca data XML ke dalam tabel hierarkis

  3. Bagaimana cara mendeteksi jika string berisi karakter khusus?

  4. Ganti kolom identitas dari int ke bigint

  5. TSQL pilih ke tabel Temp dari sql dinamis