共计 1498 个字符,预计需要花费 4 分钟才能阅读完成。
我的公众号:MarkerHub,Java 网站:https://markerhub.com
更多精选文章请点击:Java 笔记大全.md
小 Hub 领读:
数据量少的时候看不出区别,量大差异显著,文末的 4 点总结你应该去看一下,或者对你有帮忙!
- 风过无痕
- https://www.cnblogs.com/tangy…
场景
用的数据库是 mysql5.6,上面简略的介绍下场景
课程表:
数据 100 条
学生表:
数据 70000 条
学生成绩表 SC:
数据 70w 条
查问目标:
查找语文考 100 分的考生
查问语句:
执行工夫:30248.271s
为什么这么慢?先来查看下查问打算:
发现没有用到索引,type 全是 ALL,那么首先想到的就是建设一个索引,建设索引的字段当然是在 where 条件的字段。
先给 sc 表的 c_id 和 score 建个索引
再次执行上述查问语句,工夫为: 1.054s
快了 3w 多倍,大大缩短了查问工夫,看来索引能极大水平的进步查问效率,看来建索引很有必要,很多时候都遗记建索引了,数据量小的的时候压根没感觉,这优化感觉挺爽。
然而 1s 的工夫还是太长了,还能进行优化吗,认真看执行打算:
查看优化后的 sql:
补充:这里有网友问怎么查看优化后的语句
办法如下:
在命令窗口执行
有 type=all
依照我之前的想法,该 sql 的执行的程序应该是先执行子查问
耗时:0.001s
失去如下后果:
而后再执行
耗时:0.001s
这样就是相当快了啊,Mysql 居然不是先执行里层的查问,而是将 sql 优化成了 exists 子句,并呈现了 EPENDENT SUBQUERY,
mysql 是先执行外层查问,再执行里层的查问,这样就要循环 70007*11=770077 次。
那么改用连贯查问呢?
这里为了从新剖析连贯查问的状况,先临时删除索引 sc_c_id_index,sc_score_index
执行工夫是:0.057s
效率有所提高,看看执行打算:
这里有连表的状况呈现,我猜测是不是要给 sc 表的 s_id 建设个索引
CREATE index sc_s_id_index on SC(s_id);
show index from SC
在执行连贯查问
工夫: 1.076s,居然工夫还变长了,什么起因?查看执行打算:
优化后的查问语句为:
貌似是先做的连贯查问,再执行的 where 过滤
回到后面的执行打算:
这里是先做的 where 过滤,再做连表,执行打算还不是固定的,那么咱们先看下规范的 sql 执行程序:
失常状况下是先 join 再 where 过滤,然而咱们这里的状况,如果先 join,将会有 70w 条数据发送 join 做操,因而先执行 where
过滤是理智计划,当初为了排除 mysql 的查问优化,我本人写一条优化后的 sql
即先执行 sc 表的过滤,再进行表连贯,执行工夫为:0.054s
和之前没有建 s_id 索引的工夫差不多
查看执行打算:
先提取 sc 再连表,这样效率就高多了,当初的问题是提取 sc 的时候呈现了扫描表,那么当初能够明确须要建设相干索引
再执行查问:
执行工夫为:0.001s,这个工夫相当靠谱,快了 50 倍
执行打算:
咱们会看到,先提取 sc,再连表,都用到了索引。
那么再来执行下 sql
执行工夫 0.001s
执行打算:
这里是 mysql 进行了查问语句优化,先执行了 where 过滤,再执行连贯操作,且都用到了索引。
总结
1、mysql 嵌套子查问效率的确比拟低
2、能够将其优化成连贯查问
3、建设适合的索引
4、学会剖析 sql 执行打算,mysql 会对 sql 进行优化,所以剖析执行打算很重要
举荐浏览
Java 笔记大全.md
太赞了,这个 Java 网站,什么我的项目都有!https://markerhub.com
这个 B 站的 UP 主,讲的 java 真不错!