回答

收藏

LEFT JOIN显着快于INNER JOIN

技术问答 技术问答 396 人阅读 | 0 人回复 | 2023-09-14

我有一个表(MainTable),有60000多条记录。JoinTable父子关系中的第二个表()连接到自己:
% X# Q2 K1 d* ]( O, V  VSELECT   Child.ID,Parent.IDFROM     MainTableAS       ChildJOIN     JoinTable      ON Child.ID = JoinTable.IDJOIN     MainTableAS       Parent      ON Parent.ID = JoinTable.ParentID     AND Parent.SomeOtherData = Child.SomeOtherData我知道每个子记录都有父记录,而且JoinTable数据准确。
% j0 Y, N7 O9 V- Z+ H6 z5 q4 N当我操作此查询时,实际上需要几分钟。但是,如果我用左连接加入父级,运行时间不到1秒:
. w3 E$ }- w* _5 pSELECT   Child.ID,Parent.IDFROM     MainTableAS       ChildJOIN     JoinTable      ON Child.ID = JoinTable.IDLEFT JOIN MainTableAS       Parent      ON Parent.ID = JoinTable.ParentID     AND Parent.SomeOtherData = Child.SomeOtherDataWHERE    ...[some info to make sure we don't select parent records in the child dataset]...我了解到INNER JOIN结果与结果不同LEFTJOIN。在这种情况下,它的返回结果与每个孩子的父母完全相同。如果我让两个查询都运行,我可以比较数据集,它们是完全相同的。; ]3 Y" R3 [# ?  K6 ]) s' s
为什么LEFT JOIN运行速度比运行速度快得多INNER JOIN?
3 U6 r% I# P9 h9 T; h( v% WUPDATE使用内部连接时,检查查询计划并从父数据集开始。左连接时,从子数据集开始。
% p& f4 B8 X6 G' d" _* C它使用相同的索引。' `( ]0 B' B; o4 {
我能强迫它总是从孩子开始吗?使用左连接有效,但感觉不对。
5 D2 u  t+ y* K                                                               
6 `7 l7 f! r2 T% g5 {7 J6 [    解决方案:                                                                ; w, C# `, f. `
                                                                左连接似乎更快,因为强制SQL首先执行较小的选择,然后连接到较小的记录集。由于某种原因,优化器不想自然地这样做。1 P$ P. y# J% O0 X
三种强制按正确顺序连接的方法:
/ Y+ w9 f4 ~/ Q) ^+ A6 X[ol]在临时表(或表变量)中选择第一个数据子集,然后连接
3 {3 d* |; e. u7 V  G使用左连接(请记住,这可能会返回不同的数据,因为它是左连接而不是内部连接), m$ G& H' ~- k7 C! Y
使用FORCE ORDER关键字。请注意,如果表格大小或结构发生变化,查询计划可能不正确(请参考)https://dba.stackexchange.com/questions/45388/forcing-join-order)[/ol]
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则