一次非常有意思的 SQL 优化经历
场景
我用的数据库是mysql5.6,狼蚁网站SEO优化简单的介绍下场景。
文/风过无痕-唐
表
create table Course( c_id int PRIMARY KEY, name varchar(10) )
数据100条
学生表:
create table Student( id int PRIMARY KEY,name varchar(10) )
数据70000条
学生成绩表SC
CREATE table SC( sc_id int PRIMARY KEY, s_id int, c_id int, score int )
数据70w条
查询目的
查找语文考100分的考生
查询语句
select s. from Student s where s.s_id in (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 in (select s_id from SC sc where sc.c_id = 0 and sc.score = 100 )
发现没有用到索引,type全是ALL,那么想到的就是建立一个索引,建立索引的字段是在where条件的字段。
先给sc表的c_id和score建个索引
CREATE index sc_c_id_index on SC(c_id);
CREATE index sc_score_index 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 < in_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 in(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_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,竟然时间还变长了,什么原因?查看执行计划
优化后的查询语句为
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执行顺序
正常情况下是先join再进行where过滤,我们这里的情况,如果先join,将会有70w条数据发送join做操,先执行where
seo排名培训
- seo推广是什么意思呢 seo是什么推广网站
- seo免费优化网站 seo网站优化优化排名
- seo关键词排名优化 seo关键词排名优化多少钱
- seo是什么职业 seo属于什么职业
- seo具体怎么优化 seo常用优化技巧
- seo搜索引擎排名优化seo搜索引擎排名优化案例分
- seo关键词优化软件 seo网站优化软件
- seo从入门到精通 seo零基础入门到精通
- seo百度发包工具 seo发包程序
- seo推广网址 seo推广的网站和平台有哪些
- seo排名快速优化 seo技巧seo排名优化
- seo关键词优化 百度搜索关键词排名优化推广
- seo的基本步骤 seo的基本步骤顺序
- seo具体怎么优化 seo具体怎么优化内容
- seo关键词首页排名 seo关键词排名得分公式
- seo排名优化公司价格 seo排名优化服务