左連接和內連接之間在性能方面是否有區別?我使用的是SQL Server 2012.左連接和內連接之間的性能差異
回答
至少有一種情況,其中LEFT [OUTER] JOIN
比[INNER] JOIN
更好。我談到使用OUTER
而不是INNER
獲得相同的結果。
示例(我使用):
-- 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;
結果第一個查詢:
is_not_trusted name
-------------- ---------------------------------------------------------------
0 FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID
0 FK_SalesOrderDetail_SpecialOfferProduct_SpecialOfferIDProductID
執行計劃的最後兩個查詢:
注1 /查看1:如果我們看一下的執行計劃 我們看到一個FK elimination,因爲FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID
約束是可信的並且它只有一個列。但是,服務器被迫(因爲INNER JOIN Sales.SpecialOfferProduct
)從第三個表(SpecialOfferProduct)讀取數據,即使SELECT/WHERE
子句不包含此表中的任何列,並且(也)信任FK約束(FK_SalesOrderDetail_SpecialOfferProduct_SpecialOfferIDProductID)。發生這種情況是因爲這最後一個FK是多列。
注2 /瀏覽2:如果我們想在刪除讀(Scan
/Seek
)?這第二個FK是多列,對於這種情況,SQL Server無法消除FK(請參閱前面的Conor Cunnigham博客文章)。在這種情況下,我們需要將INNER JOIN Sales.SpecialOfferProduct
替換爲LEFT OUTER JOIN Sales.SpecialOfferProduct
以獲得FK消除。 SpecialOfferID
和ProductID
列都是NOT NULL
,我們有一個可信的FK參考SpecialOfferProduct
表。
@MartinSmith:我現在添加一些註釋,但在這種情況下**它們具有相同的語義。 – 2013-02-24 10:17:44
只有在引用'SpecialOfferProduct'的'SalesOrderDetail'中有'FOREIGN KEY'時,它們才具有相同的語義。 – 2013-02-24 10:24:07
@ypercube:'FK_SalesOrderDetail_SpecialOfferProduct_SpecialOfferIDProductID' – 2013-02-24 10:25:25
除了外連接可能由於保留附加行而返回更大結果集的問題之外,還有一點是優化程序在創建執行計劃時具有更大範圍的可能性,因爲INNER JOIN
是交換和聯想的。
因此,對於以下示例B
已編入索引,但A
不是。
CREATE TABLE A(X INT, Filler CHAR(8000))
INSERT INTO A
SELECT TOP 10000 ROW_NUMBER() OVER (ORDER BY @@SPID), ''
FROM sys.all_columns
CREATE TABLE B(X INT PRIMARY KEY, Filler CHAR(8000))
INSERT INTO B
SELECT TOP 10000 ROW_NUMBER() OVER (ORDER BY @@SPID), ''
FROM sys.all_columns
SELECT *
FROM B INNER JOIN A ON A.X = B.X
SELECT *
FROM B LEFT JOIN A ON A.X = B.X
優化器知道B INNER JOIN A
和A INNER JOIN B
是相同的,併產生一個計劃,試圖爲表B
一個嵌套循環。
這種轉變是不是有效的外連接和嵌套循環only supports left outer join not right outer join所以它需要使用不同的聯接類型。
但是從實際的角度來看,你應該選擇你需要的連接類型,它會給你正確的語義。
- 1. 數據連接和連接標識符之間的差異
- 2. 左連接和左連接之間的區別
- 3. Hibernate中左連接和左連接FETCH之間的區別?
- 4. 連接之間巨大的性能差異
- 5. MySQL的左連接和內連接
- 6. 字符串連接性能差異
- 7. 左連接上的內部連接使左連接表現爲內連接
- 8. Java客戶端/服務器在維護連接和重新建立連接之間的性能差異
- 9. Equijoin和內部連接差異
- 10. LINQ左外連接語法差異
- 11. SQL左連接查詢差異
- 12. 左連接和右連接
- 13. 堆疊連接性能差
- 14. SQL:左連接左連接結果左連接左連接/右連接
- 15. 我不能使用內連接和左連接在一起
- 16. 多個左連接和性能
- 17. 左連接與內部連接使用子串/左功能時
- 18. Symfony2的多個左連接,內連接
- 19. 聚合數據和連接數據之間的差異
- 20. PoolingClientConnectionManager和PoolingHttpClientConnectionManage之間的差異?哪個更適合HTTP連接?
- 21. 聯繫人html和郵件php之間的差異連接php
- 22. HTTPS連接,Android 2.3和4之間的差異
- 23. 誤差與左連接
- 24. 內部連接和列連接之間的區別
- 25. 左外連接(三個表之間的連接)?
- 26. rabbitmq中的連接池或通道之間是否存在性能差異?
- 27. MySQL的左連接,空之間的差爲值,且行
- 28. LINQ Lambda左連接與內部連接
- 29. 左連接優於內連接?
- 30. mysql左連接,MySQL做內連接?
是的,可能有區別。但你爲什麼在意?這2個不等同,並且(通常)會產生不同的結果。因此,請使用對您的查詢有用的信息,併爲您提供所需的結果。 – 2013-02-24 09:36:28
[INNER JOIN vs LEFT JOIN性能在SQL Server中]的可能的重複(http://stackoverflow.com/questions/2726657/inner-join-vs-left-join-performance-in-sql-server) – 2013-02-24 09:45:58