我有一个表(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中的数据是准确的。
当我运行此查询时,它实际上需要几分钟的时间。但是,如果我使用“左连接”加入“父级”,则运行时间不到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
之间的结果差异。在这种情况下,它返回的结果与每个 child 都有 parent 的情况完全相同。如果我让两个查询都运行,我可以比较数据集,它们是完全相同的。为什么
LEFT JOIN
的运行速度比INNER JOIN
快得多?更新
检查查询计划,并在使用内部联接时从父数据集开始。进行左连接时,它从子数据集开始。
它使用的索引都是相同的。
我可以强制它总是从 child 开始吗?使用左联接有效,只是感觉不对。
之前曾在这里问过类似的问题,但似乎没有人回答我的问题。
例如在INNER JOIN vs LEFT JOIN performance in SQL Server中选择的答案表明,左联接总是比内联接慢。该论点是有道理的,但这不是我所看到的。
最佳答案
左联接似乎更快,因为强制SQL先执行较小的选择,然后再联接到此较小的记录集。由于某种原因,优化器不希望自然地这样做。
强制以正确顺序进行连接的3种方法:
关于sql - LEFT JOIN显着快于INNER JOIN,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17100819/