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

俊达2年前技术文章1095

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

其中有一种情况是因为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||'' = ''


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

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


相关文章

Redis 命令行 redis-cli 介绍

前言redis-cli 是 Redis 自带的命令行工具,是运维和开发人员常用的工具,本篇文章将介绍它的使用技巧和一些有趣的功能。1. 连接 Redis 服务redis-cli 默认连接的是 127....

Windows自带性能监控工具Perfmon使用介绍

Windows自带性能监控工具Perfmon使用介绍

一、Perfmon简介Perfmon(Performance Monitor)是一款Windows自带的性能监控工具,提供了图表化的系统性能实时监视器、性能日志和警报管理。通过添加性能计数器(Perf...

pod内无法访问slb的监听

pod内无法访问slb的监听

问题背景在A账号下的k8s集群中有个nginx 应用,需要去访问B账号下内网slb代理的一个服务。B账号下的slb有多条监听,测试发现只有个别监听可以telnet通,其余监听telnet均不通。可能是...

helm部署gitlab

helm部署gitlab

官方文档地址添加gitlab的helm仓库helm repo add gitlab https://charts.gitlab.io/�查看已经安装的helm仓库helm repo list安装git...

可观测未来OpenTelemertry-结构化数据价值

可观测未来OpenTelemertry-结构化数据价值

前言开源软件和云供应商的软件开发模式已经改变了我们构建和部署软件的方式。集成开源软件,我们可以在很短时间内构建和部署一个应用程序。但这并不意味着使用和维护它们也变得更简单,随着应用程序的扩充,程序的调...

MySQL运维实战之备份和恢复(8.4)xtrabackup恢复全量备份

恢复全量备份恢复全量备份大致可以分成以下几步:解压备份文件、prepare备份文件、将数据copy到目标实例相关目录、启动数据库实例。解压文件如果备份时使用了xbstream,需要先解压备份文件。我们...

发表评论    

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