回答

收藏

LEFT JOIN显着快于INNER JOIN

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

我有一个表(MainTable),有60000多条记录。JoinTable父子关系中的第二个表()连接到自己:
0 A/ B* Y! z1 [9 WSELECT   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数据准确。
+ T# o$ u; N3 g当我操作此查询时,实际上需要几分钟。但是,如果我用左连接加入父级,运行时间不到1秒:
+ t# E9 S" g5 @5 V' @: s5 TSELECT   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。在这种情况下,它的返回结果与每个孩子的父母完全相同。如果我让两个查询都运行,我可以比较数据集,它们是完全相同的。
! X' C' K$ H  }' c9 _, Y; X为什么LEFT JOIN运行速度比运行速度快得多INNER JOIN?( @* `3 O# ~. K# K; j! ?: ]
UPDATE使用内部连接时,检查查询计划并从父数据集开始。左连接时,从子数据集开始。. ^7 a; |$ q/ x" O. Y
它使用相同的索引。
5 u8 [4 k# H3 @5 J' z' I- l我能强迫它总是从孩子开始吗?使用左连接有效,但感觉不对。2 u  x1 c4 `. m/ g; n" U* }* q1 A
                                                                ' o$ ^  R" L0 D1 D2 r0 N$ a- L
    解决方案:                                                                , [& j* T3 L* L/ H; X8 {
                                                                左连接似乎更快,因为强制SQL首先执行较小的选择,然后连接到较小的记录集。由于某种原因,优化器不想自然地这样做。
& v+ ]! f$ H( F! H6 t* @三种强制按正确顺序连接的方法:3 w: X. T& Q! [* u' w1 r/ x
[ol]在临时表(或表变量)中选择第一个数据子集,然后连接$ _2 a, Q' H- V' m( W. B" d
使用左连接(请记住,这可能会返回不同的数据,因为它是左连接而不是内部连接)  T- ^5 M8 e! |8 _( w% p! A+ y
使用FORCE ORDER关键字。请注意,如果表格大小或结构发生变化,查询计划可能不正确(请参考)https://dba.stackexchange.com/questions/45388/forcing-join-order)[/ol]
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则