MySQL慢查优化 循环/嵌套子查询(DEPENDENT SUBQUERY)

系列文章目录



前言

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。
在这里插入图片描述


虽然 MySQL5.6 引入了物化特性,但需要特别注意它目前仅仅针对查询语句的优化。对于更新或删除需要手工重写成 JOIN。
在这里插入图片描述
借助 explain 执行计划来分析索引失效的具体场景。看到 SQL 执行计划中select_type字段中出现“DEPENDENT SUBQUERY”时,要特别注意。

来看一个SQL

EXPLAIN SELECT t.id FROM student t WHERE t.is_del=0 and t.classin_err_times<10 
 AND (SELECT count(*) FROM classin_student ct WHERE ct.stu_id=t.id)<1 ORDER BY t.id DESC;

系统会给学员生成一个信息,生成后会录入到classin_student,这里要查找没有录入该信息的学员,就是ID不在classin_student表中的数据。
在这里插入图片描述
看执行计划

DEPENDENT SUBQUERY

在SELECT或WHERE列表中包含了子查询,子查询基于外层

官方含义为:

SUBQUERY:子查询中的第一个SELECT;

DEPENDENT SUBQUERY:子查询中的第一个SELECT,取决于外面的查询 。

MySQL执行逻辑是,先根据is_del和classin_err_times把外层数据查出来,然后根据外层的查询结果,又走了一个子查询,这个子查询的执行依赖于外层结果量。

建议使用JOIN进行优化

EXPLAIN SELECT t.id FROM student t LEFT JOIN classin_student ct ON t.id = ct.stu_id 
WHERE t.is_del = 0  AND t.classin_err_times < 10 AND IFNULL(ct.id, 0) = 0;

查看执行计划,成了两个SIMPLE查询。

在这里插入图片描述
附录:

DBA观点引用:MySQL 子查询的弱点:mysql 在处理子查询时,会改写子查询。

通常情况下,我们希望由内到外,先完成子查询的结果,然后再用子查询来驱动外查询的表,完成查询。

例如:

select * from test where tid in (select fk_tid from sub_test where gid=10)

通常我们会感性地认为该 sql 的执行顺序是:

sub_test 表中根据 gid 取得 fk_tid(2,3,4,5,6)记录,

然后再到 test 中,带入 tid=2,3,4,5,6,取得查询数据。

但是实际mysql的处理方式为:

select * from test where exists (
select * from sub_test where gid=10 and sub_test.fk_tid=test.tid)

mysql 将会扫描 test 中所有数据,每条数据都将会传到子查询中与 sub_test 关联,子查询不会先被执行,所以如果 test 表很大的话,那么性能上将会出现问题。

  • 19
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java毕设王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值