一次非常有意思的 SQL 优化经历
场景
我用的数据库是mysql5.6,下面简单的介绍下场景。
文/风过无痕-唐
表
create table Course( c_id t PRIMARY KEY, name varchar(10) )
数据100条
学生表:
create table Student( id t PRIMARY KEY,name varchar(10) )
数据70000条
学生成绩表SC
CREATE table SC( sc_id t PRIMARY KEY, s_id t, c_id t, score t )
数据70w条
查询目的
查找语文考100分的考生
查询语句
select s. from Student s where s.s_id (select s_id from SC sc where sc.c_id = 0 and sc.score = 100 )
执行时间30248.271s
晕,为什么这么慢,先来查看下查询计划
EXPLAIN select s. from Student s where s.s_id (select s_id from SC sc where sc.c_id = 0 and sc.score = 100 )
发现没有用到索引,type全是ALL,那么想到的就是建立一个索引,建立索引的字段是在where条件的字段。
先给sc表的c_id和score建个索引
CREATE dex sc_c_id_dex on SC(c_id);
CREATE dex sc_score_dex on SC(score);
执行上述查询语句,时间为: 1.054s
快了3w多倍,大大缩短了查询时间,看来索引能极大程度的提高查询效率,建索引很有必要,很多时候都忘记建
索引了,数据量小的的时候压根没感觉,这优化的感觉挺爽。
1s的时间还是太长了,还能进行优化吗,仔细看执行计划
查看优化后的sql:
SELECT `YSB`.`s`.`s_id` AS `s_id`, `YSB`.`s`.`name` AS `name`FROM `YSB`.`Student` `s` WHERE < _optimizer > ( `YSB`.`s`.`s_id` ,< EXISTS > ( SELECT 1 FROM `YSB`.`SC` `sc` WHERE ( (`YSB`.`sc`.`c_id` = 0) AND (`YSB`.`sc`.`score` = 100) AND ( < CACHE > (`YSB`.`s`.`s_id`) = `YSB`.`sc`.`s_id` ) ) ) )
补充这里有网友问怎么查看优化后的语句,
推广,,长沙,,
方法如下
在命令窗口执行
有type=all
按照我之前的想法,该sql的执行的顺序应该是先执行子查询
select s_id from SC sc where sc.c_id = 0 and sc.score = 100
耗时0.001s
得到如下结果
然后再执行
select s. from Student s where s.s_id (7,29,5000)
耗时0.001s
这样就是相当快了啊,Mysql竟然不是先执行里层的查询,而是将sql优化成了exists子句,并出现了EPENDENT SUBQUERY,
mysql是先执行外层查询,再执行里层的查询,这样就要循环700078次。
那么改用连接查询呢?
SELECT s. from Student s INNER JOIN SC sc on sc.s_id = s.s_id where sc.c_id=0 and sc.score=100
这里为了重新分析连接查询的情况,先暂时删除索引sc_c_id_dex,sc_score_dex
执行时间是0.057s
效率有所提高,看看执行计划
这里有连表的情况出现,我猜想是不是要给sc表的s_id建立个索引
CREATE dex sc_s_id_dex on SC(s_id);
show dex from SC
在执行连接查询
时间: 1.076s,竟然时间还变长了,什么原因?查看执行计划
优化后的查询语句为
SELECT `YSB`.`s`.`s_id` AS `s_id`, `YSB`.`s`.`name` AS `name`FROM `YSB`.`Student` `s`JOIN `YSB`.`SC` `sc` WHERE ( ( `YSB`.`sc`.`s_id` = `YSB`.`s`.`s_id` ) AND (`YSB`.`sc`.`score` = 100) AND (`YSB`.`sc`.`c_id` = 0) )
貌似是先做的连接查询,再进行的where条件过滤
回到前面的执行计划
这里是先做的where条件过滤,再做连表,执行计划还不是固定的,那么我们先看下标准的sql执行顺序
正常情况下是先jo再进行where过滤,我们这里的情况,如果先jo,将会有70w条数据发送jo做操,先执行where
网站seo
- 洛扎企业官网搭建公司:提升品牌形象与网络实
- 北京百度快照排名怎么把网站排名在百度首页
- 湖南seo网站排名关键词优化如何提升销售额和销
- 打造企业形象的利器:金塔企业官网搭建公司
- 提升平舆百度快照排名的全面指南
- 浙江企业网站优化怎样做网站排名
- 云南整站优化:提升网站价值的关键
- 西藏新手做seo怎么做发展潜力如何
- 提升扬州网站排名优化的有效策略
- 中山建站公司有哪些:全面解析与推荐
- 长寿百度关键词SEO:提升你的网站排名技巧
- 寻找优质服务的秘诀:库车会SEO的网站建设公司
- 兴义企业网站优化:提升网站可见性的策略与方
- 威海优化关键词排名推广:提升您网站流量的有
- 松原建站公司:助力企业数字化转型的最佳选择
- 罗甸企业官网搭建公司:助力企业数字化转型