MySQL性能优化(三)函数运算导致无法使用索引

俊达2年前技术文章918

有时侯我们会遇到这样的情况:明明字段上已经建立了索引,但是查询还是无法使用索引。

其中有一种情况是因为SQL中对索引字段进行了运算。

一个例子

select * from user
where date(gmt_modified) = date(now())


执行计划

3-1.png

从执行计划可以看到,possible_keys是空的,没有任何索引可用。但实际上gmt_modified上是有索引的。

因为where条件对gmt_modified做了函数运算,导致无法使用索引。


改写SQL

这种情况下,我们可以对SQL进行改写,避免在索引子弹上使用函数,同时保持SQL的逻辑不变。

对于这个案例中的SQL,我们可以这么改写:

select * from user 
where gmt_modified >= date(now()) 
and gmt_modified < date(date_add(now(), interval 1 day))


这2个SQL的逻辑一样,都是获取修改时间为当天的用户信息。改写之后,我们再来看执行计划:


3-2.png


可以看到,改写后,SQL用到了idx_gmt_modified索引。扫描的记录数为3119。而之前全表扫描需要访问2.8万行数据。


总结

索引子弹上的函数运算还会以其他形式出现,如:

select * from t1 where b+0 = 0;

select * from t1 where cc||'' = ''


除了对索引字段进行显式的运算,还存在另外一种更隐蔽的情况:字段类型隐式转换。

关于字段类型隐式转换的例子,我们在后续的文章中介绍。


相关文章

高效便捷!解锁阿里云跨账号专线互联的全新实施方案

高效便捷!解锁阿里云跨账号专线互联的全新实施方案

01背    景为持续提升金融云环境的合规标准以及可用区内产品服务的性能和稳定性,阿里云将对杭州地域BCD三个金融云可用区进行基础设施架构升级与改造,对应可用区云产品将于 2024...

Hbase2.x 使用hbck2

Hbase2.x 使用hbck2

1、背景默认情况下apache hbase 使用hbck2时,无法使用-j 来加载hbck2的jar包,无法进行修复2、解决办法是由于默认情况下只使用自带的hbase hbck修复命令,大部分功能在2...

K8s数据持久化

K8s数据持久化

一、为什么需要持久化为了解决pod里面的容器被删除后数据不丢失,则引入了存储类型,类似于docker中的数据卷。在kubernetes集群中,其是支持多种存储类型,包括但不限于emptyDir,Hos...

haproxy服务无法正常启动

haproxy服务无法正常启动

【局点信息】测试环境【集群信息】【问题现象】haproxy设置配置文件后,无法正常启动,查看服务状态显示失败配置增加内容#增加如下配置 listen ApiApplicationServer   ...

alluxio短路读

alluxio短路读

原理当Client和Worker在同一节点时,客户端对本地缓存数据的读写请求可以绕过RPC接口,使本地文件系统可以直接访问Worker所管理的数据,这种情况被称为短路写,速度比较快,如果该节点没有Wo...

Hive中小表与大表关联(join)的性能分析

经常看到一些Hive优化的建议中说当小表与大表做关联时,把小表写在前面,这样可以使Hive的关联速度更快,提到的原因都是说因为小表可以先放到内存中,然后大表的每条记录再去内存中检测,最终完成关联查询。...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。