为什么我加了索引,SQL执行还是这么慢(一)?
2019-11-11 00:23
1161 查看
在MySQL中,有一些语句即使逻辑相同,执行起来的性能差异确实极大的。
先抛出一个结论:如果想使用索引树搜索功能,就不能使用数据库函数来处理索引字段值,而是在不改变索引字段值的同时,自己通过SQL语句来实现逻辑
条件字段函数操作
假设我们现在维护了一张系统交易表:
mysql> CREATE TABLE `tradelog` ( `id` int(11) NOT NULL, `tradeid` varchar(32) DEFAULT NULL, `operator` int(11) DEFAULT NULL, `t_modified` datetime DEFAULT NULL, PRIMARY KEY (`id`), KEY `tradeid` (`tradeid`), KEY `t_modified` (`t_modified`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
我们在表中插入5条测试数据:
insert into tradelog (id,tradeid,t_modified) values(1,'a','2017-03-15'); insert into tradelog (id,tradeid,t_modified) values(2,'b','2017-06-11'); insert into tradelog (id,tradeid,t_modified) values(3,'c','2017-07-03'); insert into tradelog (id,tradeid,t_modified) values(4,'d','2018-08-11'); insert into tradelog (id,tradeid,t_modified) values(5,'e','2018-09-12');
SQL执行结果
接下来我们需要查询2016年到2018年,所有7月份的数据。
SQL可以这样写:
select count(*) from tradelog where month(t_modified)=7;
我们可以通过explain命令,对这行语句的执行结果进行分析。
SQL执行结果
即该语句使用了t_modified索引,row=5,代表了该语句进行了全索引扫描,Using index表示使用了覆盖索引。
那么为什么会这样呢?
首先执行操作用哪个索引,是优化器决定的,这里可以使用的索引是主键索引和t_modified索引。在对比索引树大小后发现,t_modified索引树更小,所以优化器选择使用t_modified索引,但是为什么还会使用全索引扫描,而不是索引树查找的方式呢?原因是innodb索引树查找的方式,是由于同级的兄弟节点具有顺序性(类似于二分查找,要求数据有序),锁索引值的顺序性被破坏,优化器就只能选择全索引扫描的方式执行语句,所以
对索引字段的函数操作,会破坏索引值的顺序性,导致优化器放弃走索引树搜索功能。
我们如果想使用索引树搜索功能,就不能使用数据库函数来处理索引字段值,而是在不改变索引字段值的同时,自己通过SQL语句来实现逻辑,上述SQL语句可做如下的改写:
select count(*) from tradelog where (t_modified >= '2016-7-1' and t_modified<'2016-8-1') or (t_modified >= '2017-7-1' and t_modified<'2017-8-1') or (t_modified >= '2018-7-1' and t_modified<'2018-8-1');
接着我们使用explain对其进行分析:
SQL执行结果
此时我们可以看出,此时该语句采用了树搜索的方式,只扫描了3行数据。
相关文章推荐
- 为什么我加了索引,SQL执行还是这么慢(二)?
- 为什么我只查一行的语句,执行的还是这么慢?
- web前端这么缺人,为什么还是找不到工作
- 执行计划之误区,为什么COST很小,SQL却跑得很慢?
- mysql sql语句执行时是否使用索引检查方法
- 执行3小时超长SQL的分析优化过程:从索引遇见IS NULL,到最佳实践
- 在access中执行SQL,SQL中包含IIF,取出来的结果集字符串被截断了,请教各位大侠,这个是为什么呀?谢谢!
- 不看后悔的腾讯面试题:SQL语句为什么执行的很慢?
- 为什么v$sql中的执行次数会被重置(续)
- 为什么你的SQL执行很慢
- ssm框架为什么无论如何修改controller类哪怕重新导入还是执行之前的项目
- thinkphp为什么SQL语句执行了还要报错
- sybase数据库中索引导致sql语句执行不成功
- 每天上班都坐着,为什么还是这么累?
- 执行sql语句中 为什么应该尽量减少“SELECT *”这类语句的使用
- 为什么Oracle有时会用索引来查找数据?--强制Oracle使用最优的“执行计划”
- Oracle的HINT可以强制指定SQL的执行计划,比如选择索引、表的连接顺序以及表的连接方式等等。(转)
- 【转】同一个SQL查询语句,为什么使用到的索引不同?
- Sql Server之旅——第七站 为什么都说状态少的字段不能建索引
- MySQL中的索引以及为什么要用索引,还有数据库中那些SQL语句会引起全表扫描