左连接和内连接之间在性能方面是否有区别?我使用的是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. 连接之间巨大的性能差异
- 4. 字符串连接性能差异
- 5. 左连接上的内部连接使左连接表现为内连接
- 6. Java客户端/服务器在维护连接和重新建立连接之间的性能差异
- 7. SQL左连接查询差异
- 8. 左连接和右连接
- 9. 堆叠连接性能差
- 10. 我不能使用内连接和左连接在一起
- 11. 左连接与内部连接使用子串/左功能时
- 12. 多个左连接和性能
- 13. HTTPS连接,Android 2.3和4之间的差异
- 14. 左外连接(三个表之间的连接)?
- 15. 内部连接和列连接之间的区别
- 16. LINQ Lambda左连接与内部连接
- 17. 左连接优于内连接?
- 18. 这两个JDBC连接之间是否存在任何性能差异?
- 19. 多列性能的左连接?
- 20. 内连接和where()子句的性能?
- 21. 如何使用左连接和/或右连接和/或内连接
- 22. 的Django ForeignKey的与空=真,内部连接和左外连接
- 23. SQL左连接(条件之间)
- 24. 修改具有左连接和内连接的查询
- 25. linq查询内部连接和左连接的问题
- 26. 内连接和左连接在相同的SQL查询
- 27. 右连接与左连接
- 28. 实现差异连接和右外连接在LINQ
- 29. html5和mysql之间的直接连接
- 30. Swazoo和Komanche之间的性能差异?
是的,可能有区别。但你为什么在意?这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