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

俊达3年前技术文章1684

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

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


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

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


相关文章

Linux网络扫描和嗅探工具—Nmap

1、简介Nmap,也就是Network Mapper,是Linux下的网络扫描和嗅探工具包。它由Fyodor编写并维护。由于Nmap品质卓越,使用灵活,它已经是渗透测试人员必备的工具。其基本功能有三个...

kafka部署建议

1       集群部署规范1.1      Cpu规格与挂盘数量的关系 &nb...

大数据即席查询-Presto

一、Presto 概念Presto 是一个开源的分布式 SQL 查询引擎,数据量支持 GB 到 PB 字节,主要用来秒级查询的场景。注:虽然 Presto 可以解析 SQL,但它不是一个标准的数据库。...

hive 报 找不到或无法加载主类 org.apache.hadoop.mapreduce.v2.app.MRAppMaster

hive 报 找不到或无法加载主类 org.apache.hadoop.mapreduce.v2.app.MRAppMaster

解决办法:关键需要配置两个配置:mapred-site.xml 和 yarn-site.xml下面配置hadoop classpath。先运行shell命令:hadoop classpath添加一个配...

Flink关于HiveCatalog

HiveCatalogHiveCatalog 有两个用途:作为原生 Flink 元数据的持久化存储,以及作为读写现有 Hive 元数据的接口。配置在flink-sql-connector-hive-1...

hdfs短路读

hdfs短路读

原理当客户端执行数据块副本短路读时,Client与DataNode的交互过程具体如下图:含义如下:(1)DFSClient通过requestShortCircuitShm()接口向DataNode请求...

发表评论    

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