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

俊达3年前技术文章1261

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

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


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

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


相关文章

网络数据链路层-MAC帧(2)

网络数据链路层-MAC帧(2)

3.ARP协议地址解析协议(Address Resolution Protocol,ARP)协议,是根据IP地址获取MAC地址的一个TCP/IP协议。3.1为什么有ARP协议?ARP 协议建立了主机...

阿里云ES跨账号数据迁移(reindex)

阿里云ES跨账号数据迁移(reindex)

1、背景与前置条件总的来说,阿里云es集群间数据迁移,有三中方式,logstash、reindex、镜像备份恢复,分别使用不同的场景,本文档主要讨论reindex方式进行账号下,ES跨集群迁移时,使用...

SQL隐式转换导致索引失效_数据类型不一致

SQL隐式转换导致索引失效_数据类型不一致

2.数据类型不一致导致索引失效示例 SQL 如下,SQL 本身很简单,但通过查看执行计划可以发现,此时走的是主键索引,查看表结构发现表的 kemu 是有索引的,且过滤性相对较好。进一步核实,SQL 为...

为什么根据时间戳获取topic的offset为空呢

为什么根据时间戳获取topic的offset为空呢

一、前言最近有一个需求,要查询某一时间戳对应的offset值,于是就想到了使用 ./bin/kafka-run-class.sh kafka.tools.GetOffsetShell --time &...

Python Web 自动化测试工具 — Selenium

Selenium 是一个 Web 自动化测试工具,Selenium 通过非常简洁方便的 API,使用 Selenium WebDrivers(Selenium web 驱动器)像使用 Firefox,...

11g单实例adg部署

一、环境规划搭建adg需要备端完成rdbms软件安装这一步和监听配置,不需要安装数据库。注意:db_unique_name 主备库不能相同db_name主备库需保持一致主备库DB版本需保持一致信息项主...

发表评论    

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