当前位置:   article > 正文

SqlServer与MySql的JOIN、Left JOIN、Right Join表的执行顺序问题_left join 大表放前面

left join 大表放前面

写这个文章的起因是,因为面试的时候又面试官问我,a left join b和b right join a,有什么区别,我说没什么区别,查询结果一样,性能也一样,那个面试官便说,小表和大表的前后顺序对性能是有影响的,他说sql语句从左往右执行,如果左边是大表,会先扫描左边的表的数据,然后再扫描右边表的数据,真是误人子弟啊!下面用实践来打他脸!

我会有SqlServer和MySql分别做实践,因为这两个数据库在Sql执行解析的机制还是有很大不同的。

SqlServer:

tEBay_Trade=》数据量500W        tPublic_Shop=>数据量30
  1. -----如果where条件命中索引 且只有一个索引
  2. --关于join 不管是大表在前还是小表在前,查询顺序总是以where索引所在表为第一扫描的表
  1. select * from tPublic_Shop s
  2. join tEBay_Trade t on s.id=t.ShopID
  3. where s.Id>10

  1. select * from tPublic_Shop s
  2. join tEBay_Trade t on s.id=t.ShopID
  3. where t.CreateDate>'2021-01-01'

--对于left join和right join 总是会以where条件索引所在的表为第一扫描表
  1. select * from tEBay_Trade t
  2. left join tPublic_Shop s on s.id=t.ShopID
  3. where t.CreateDate>'2021-01-01'

 

  1. select * from tPublic_Shop s
  2. left join tEBay_Trade t on s.id=t.ShopID
  3. where t.Id>10

  1. select * from tPublic_Shop s
  2. right join tEBay_Trade t on s.id=t.ShopID
  3. where t.CreateDate>'2021-01-01'

  1. -----如果where条件命中索引 且有多个索引
  2. --关于join 不管大表在前还是小表在后,如果有多个where条件命中索引,那么会以索引对应的最大的那个表为第一扫描表
  1. select * from tPublic_Shop s
  2. join tEBay_Trade t on s.id=t.ShopID
  3. where s.Id>10 and t.CreateDate>'2021-01-01'

 

  1. select * from tEBay_Trade t
  2. join tPublic_Shop s on s.id=t.ShopID
  3. where t.CreateDate>'2021-01-01' and s.Id>10

 

  1. -----如果没有索引或where条件未命中索引
  2. --join 如果没有索引或where条件未命中索引,系统会自动选择小表作为第一扫描表
  1. select * from tPublic_Shop s
  2. join tEBay_Trade t on s.id=t.ShopID

  1. select * from tEBay_Trade t
  2. join tPublic_Shop s on s.id=t.ShopID

--left join和right join 如果没有索引或where条件未命中索引,系统会自动选择小表作为第一扫描表
  1. select * from tEBay_Trade t
  2. left join tPublic_Shop s on s.id=t.ShopID

 

  1. select * from tPublic_Shop s
  2. left join tEBay_Trade t on s.id=t.ShopID

 

  1. select * from tPublic_Shop s
  2. right join tEBay_Trade t on s.id=t.ShopID

MySql这货就很不一样了,正规的跟野生的差别很明显:

tuser数据量:33954    torder数据量:4612

#关于join 不管索引是不是加在主表上,总是先扫描最小的表
  1. select * from tuser u
  2. join torder t on u.id=t.uid
  3. where u.id>500

  1. select * from tuser u
  2. join torder t on u.id=t.uid
  3. where t.createtime>='2021-07-01'

  1. select * from torder t
  2. join tuser u on u.id=t.uid
  3. where u.id>500

#不管是left join还是right join,如果没有条件命中索引,都是以主表为第一扫描的表
  1. select * from torder t
  2. left join tuser u on u.id=t.uid

  1. select * from tuser u
  2. right join torder t on u.id=t.uid

  1. select * from tuser u
  2. left join torder t on u.id=t.uid

 

#不管是left join还是right left,如果where条件命中索引,会以这个索引对应的表为第一扫描的表
  1. select * from torder t
  2. right join tuser u on u.id=t.uid
  3. where t.createtime>='2021-07-01'

  1. select * from torder t
  2. right join tuser u on u.id=t.uid
  3. where u.id>500

  1. select * from tuser u
  2. left join torder t on u.id=t.uid
  3. where t.createtime>='2021-07-01'

  1. select * from tuser u
  2. left join torder t on u.id=t.uid
  3. where u.id>500

 

总结:

关于SqlServer:

1、对于join,left join,right join,不管是大表在前还是小表在前,如果where条件命中索引,总会以where条件索引所在表为第一扫描的表

2、对于join,left join,right join,不管是大表在前还是小表在前,如果where条件命中索引,而且是多个索引,那么会以索引对应的最大的那个表为扫描的第一个表

3、对于join,left join,right join,不管是大表在前还是小表在前,如果where条件没有命中索引,系统会自动选择小表作为第一扫描表

关于MySql:

1、对于join,不管是大表在前还是小表在前,如果where条件命中索引,总是先扫描小表,而不是索引所在的表

2、对于left join和right join,不管是大表在前还是小表在前,如果where条件命中索引,会以索引对应的这个表为第一扫描的表

3、对于left join和right join,不管是大表在前还是小表在前,如果没有条件命中索引,都是以主表为第一扫描的表

所以:表的执行顺序是不以人的主管意志为转移的,如果自己不清楚,请不要随便讲出来。实践是检验真理的唯一标准

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/724987
推荐阅读
相关标签
  

闽ICP备14008679号