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

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

SqlServer:

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

mysql left join 主表为什么不走索引 mysql join为什么小表放前面_sql语句

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

mysql left join 主表为什么不走索引 mysql join为什么小表放前面_执行顺序_02

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

 

mysql left join 主表为什么不走索引 mysql join为什么小表放前面_执行顺序_03

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

mysql left join 主表为什么不走索引 mysql join为什么小表放前面_Sql_04

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

mysql left join 主表为什么不走索引 mysql join为什么小表放前面_执行顺序_05

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

 

mysql left join 主表为什么不走索引 mysql join为什么小表放前面_sql语句_06

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

 

mysql left join 主表为什么不走索引 mysql join为什么小表放前面_执行顺序_07

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

mysql left join 主表为什么不走索引 mysql join为什么小表放前面_Sql_08

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

mysql left join 主表为什么不走索引 mysql join为什么小表放前面_sql语句_09

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

 

mysql left join 主表为什么不走索引 mysql join为什么小表放前面_Sql_10

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

 

mysql left join 主表为什么不走索引 mysql join为什么小表放前面_sql语句_11

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

mysql left join 主表为什么不走索引 mysql join为什么小表放前面_执行顺序_12

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

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

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

mysql left join 主表为什么不走索引 mysql join为什么小表放前面_数据_13

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

mysql left join 主表为什么不走索引 mysql join为什么小表放前面_执行顺序_14

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

mysql left join 主表为什么不走索引 mysql join为什么小表放前面_数据_15

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

mysql left join 主表为什么不走索引 mysql join为什么小表放前面_Sql_16

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

mysql left join 主表为什么不走索引 mysql join为什么小表放前面_Sql_17

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

 

mysql left join 主表为什么不走索引 mysql join为什么小表放前面_Sql_18

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

mysql left join 主表为什么不走索引 mysql join为什么小表放前面_数据_19

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

mysql left join 主表为什么不走索引 mysql join为什么小表放前面_数据_20

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

mysql left join 主表为什么不走索引 mysql join为什么小表放前面_执行顺序_21

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

 

mysql left join 主表为什么不走索引 mysql join为什么小表放前面_数据_22

总结:

关于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,不管是大表在前还是小表在前,如果没有条件命中索引,都是以主表为第一扫描的表

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