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.