(详细深入)使用索引优化left join on + where条件查询

首先,贴一个待优化的sql语句

select * from A left join B on A.c = B.c where A.employee_id = 3

需求解读:

  • A表left join B表,并且指定A表中的employee_id为一个具体的值
在c字段不是任何索引,A B 表各有1W多条数据的情况下,用explain分析得知,AB表都使用了全表查询,效率极低
image.png

而我们执行这句sql的时间,即使使用的是本地SSD硬盘也达到了惊人的16S

image.png

优化 :

  • 给AB表都加索引列c
    这一点网上都有大片介绍,但网上的说明也就到此为止而已

让我们看看结果

image.png

可以看到,确实是使用了索引!我们看看执行分析
image.png

16s多的查询,仅用了0.1s!很多人的优化之路到这里就结束了,但真的大功告成了吗?


分析得知,查询看似快了不少,然而表A还是进行了全表查询,而我们的查询中使用了where语句,根本就不需要全表扫描!!

那么问题来了:where条件中employee_id 的索引应该怎么加?

尝试解决:

  • 将A表中的索引改为employee_id+c
    image.png

    sql分析:
    image.png

看似没有问题?确实是用到了employee_id+c的索引,但是

思考:sql执行 from中的on应该是优先于where语句的,为什么这里employee_id反而在c之前?有违常理?

结合上面的Mysql优化可知,
这一句Sql在执行的时候首先是选择了使用表B的索引来进行优化,
将表A单独放出来进行后续的操作,
然后,又发现了where语句中A.employee_id有一个聚合索引,
并且employee_id处于索引头,所以这个聚合索引是可用的,
so自然使用了此索引

为了证明这个观点,我们把聚合索引后面的列c删掉试试

image.png

sql分析:
image.png

查询结果和刚才的聚合索引没有任何变化,证明我们的猜测是正确的

看看最终的查询时间:

image.png

扫描的A表中记录数从10557条缩小到了符合A.employee_id=3的69条,100多倍的差距!

如果数据量不是1万 而是100万,100亿,沿用之前的sql,系统还能稳定运行吗?


开发中,哪怕是再小的问题,也要时刻保持钻研的态度,空杯心态不能丢!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。