我有一个表格(MainTable
),其中包含超过600,000条记录。它通过第二个表格(JoinTable
)以父/子类型关系连接到自己:
SELECT Child.ID, Parent.ID
FROM MainTable
AS Child
JOIN JoinTable
ON Child.ID = JoinTable.ID
JOIN MainTable
AS Parent
ON Parent.ID = JoinTable.ParentID
AND Parent.SomeOtherData = Child.SomeOtherData
我知道每个子记录都有一个父记录,JoinTable中的数据是准确的。
当我运行这个查询时,需要几分钟才能完成。但是如果我使用左连接加入Parent,则只需要不到1秒钟即可完成:
SELECT Child.ID, Parent.ID
FROM MainTable
AS Child
JOIN JoinTable
ON Child.ID = JoinTable.ID
LEFT JOIN MainTable
AS Parent
ON Parent.ID = JoinTable.ParentID
AND Parent.SomeOtherData = Child.SomeOtherData
WHERE ...[some info to make sure we don't select parent records in the child dataset]...
我理解
INNER JOIN
和 LEFT JOIN
结果之间的区别。在这种情况下,返回的结果与每个子项都有父项相同。如果让两个查询都运行,可以比较数据集,它们完全相同。为什么
LEFT JOIN
运行速度比 INNER JOIN
快那么多?
更新: 检查了查询计划,使用内连接时它从父数据集开始。当使用左连接时,它从子数据集开始。
使用的索引都是相同的。
我能否强制它始终从子数据集开始?使用左连接可以解决问题,但感觉不太对。
之前这里有类似的问题,但似乎没有回答我的问题。
例如,在INNER JOIN vs LEFT JOIN performance in SQL Server中所选的答案指出,左连接总是比内连接慢。这个论点很有道理,但它并不符合我的观察结果。
LEFT JOIN
并不比INNER JOIN
更快。事实上,它更慢;按定义,外连接(LEFT JOIN
或RIGHT JOIN
)必须完成所有内连接的工作加上扩展结果的额外工作。由于返回的行数更多,预计也会增加总执行时间,仅因结果集大小更大。 - Shafizadeh