索引优化作业

前言

辣鸡的我写索引优化作业遇到一个很奇怪的问题。

大概就是,在500w行数据的order表中,找出年龄小于20order列表,看能否使用索引进行查询优化。

创建索引、查询时间、查询计划一套做下来,发现优化器没有用创建的索引。于是开始寻找问题。

过程

首先很自然地用下面的语句进行测试

1
select * from orders where age < 20; 

发现在没加索引的时候,查询时间,explain计划如下

加了个单列普通索引

1
alter table orders add index ageindex(age);

再执行语句发现,查询时间和explain计划没变,说明优化器没有使用新建的索引

强制使用索引,加上force index(ageindex),获得查询时间和explain结果如下

图中可见,索引确实让过滤数值和row值都优化了,但是时间却大大增加了,而传输时间更是多了太多。

接着做第二题,查找姓王的人,类似的题目。但是不管用普通索引还是全文索引,优化器都不用索引。

后来改换思路,把要查询语句改成只返回主键

1
select id from orders where age < 20;

突然峰回路转,索引被使用,查询时间立刻降低

原来select *才是罪魁祸首

深入

SQL语句为什么使用select * 会降低查询速度?

大佬说了,select* 杜绝了覆盖索引的可能性。虽然上面的索引在查询计划里看起来过滤了大量数据,但

首先通过辅助索引过滤数据,然后通过聚集索引获取所有的列,这就多了一次b+树查询,速度必然会慢很多。首先通过辅助索引过滤数据,然后通过聚集索引获取所有的列,这就多了一次b+树查询,速度必然会慢很多。

磁盘io导致查询开销陡增,反倒不如全表顺序查询时间少。当索引节约的成本能以抵消、甚至远远低于磁盘io要付出的代价时,优化器自然选择放弃索引。

所以假如要求是select *,在不考虑维护的情况下,不如建立包含全列的多列索引。

最后

索引是个很重要的优化方法,经过这么多年的发展,网上已经有很多各种经验之谈,不过了解原理还是很重要啊。

《高性能mysql》得好好看一看才行。

本文标题:索引优化作业

文章作者:松子

发布时间:2018年10月26日 - 00:10

最后更新:2022年03月21日 - 23:03

博文链接:https://songzi.info/post/f3c7f886/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

0%