记一次Mysql不走日期字段索引的原因小结


Posted in MySQL onOctober 24, 2021

背景

在一个表中,dataTime字段设置是varchar类型,存入的数据是日期格式的数据,并且为该字段设置了索引。但是在日志记录中,有一条关于该表的慢查询。查询语句为:
select * from digitaltwin_meteorological where dataTime > '2021-10-15';
explain分析sql语句,发现sql语句执行了全表扫描。为何sql中用了dataTime索引列,为啥还走全表扫描呢?

探索

一:起初,认为是dataTime字段类型为varchar,所以mysql在索引排序时,按照字符串顺序进行排序了,而不是日期大小顺序进行排序的,所以在范围查询时,并不能按照日期顺序进行索引的范围分区。于是把dataTime改为datatime类型,在分析语句,发现还是全表扫描。

二:改变查询条件的值,

select count(*) from digitaltwin_meteorological where dataTime > '2021-10-15';

执行结果为3910。

EXPLAIN select * from digitaltwin_meteorological where dataTime > '2021-10-15';

sql语句分析结果为全表扫描:

记一次Mysql不走日期字段索引的原因小结

我们把查询条件改为16号,看有多少条数据:

select count(*) from digitaltwin_meteorological where dataTime > '2021-10-16';

查询结果为2525,下面我们分析16号的查询语句:

EXPLAIN select * from digitaltwin_meteorological where dataTime > '2021-10-16';

执行结果为range查询,利用到了索引:

记一次Mysql不走日期字段索引的原因小结

由此可见,当查询出来的记录条数多时,mysql会走全表扫描,认为全表扫描的效率更快。当查询出来的记录少时,mysql会使用索引查询。
全表的数据量为19714条数据,也就是说当2525/19714=13%的时候,mysql走索引查询。当3910/19714=20%的时候,mysql走全表扫描。

三:我们把dataTime该为了datetime数据类型,那么查询条件是否还需要加引号呢,我们把dataTime查询条件的引号去掉,看结果:

EXPLAIN select * from digitaltwin_meteorological where dataTime > 2021-10-16;

记一次Mysql不走日期字段索引的原因小结
可见,去掉引号后,又成了全表扫描。所以说,不管字段类型是varchar还是datetime,查询条件的值都需要加引号。而不加引号,mysql会把这个值做一些运算操作,其实不加引号后2021-10-16就不再是16号的日期了,我们看如下sql:

select count(*) from digitaltwin_meteorological where dataTime > 2021-10-16;

计算结果为19714,全表的数据,所以说,datetime查询条件也需要加引号。

四:如上的分析,都是dataTime在datetime类型情况下的讨论。而最初的字段类型是varchar,那么改成varchar类型,如上的结论还存在吗,我们修改类型,再执行sql:

EXPLAIN select * from digitaltwin_meteorological where dataTime > '2021-10-16';

记一次Mysql不走日期字段索引的原因小结

可以看到,改成varchar类型后,16号查询成了全表扫描,而不是range扫描。
把条件改成17号,看执行结果:

EXPLAIN select * from digitaltwin_meteorological where dataTime > '2021-10-17';

记一次Mysql不走日期字段索引的原因小结

17号的查询走了索引查询。我们看17号的数据量是1749。
所以,在字段类型为varchar时,1749/19714=9%的情况下,会走索引,而2525/19714=13%的情况下,会全表扫描。
也就是说当是datetime类型时,查询结果占13%的情况下,会走索引查询,而当是varchar类型时,查询结果占全表数据的13%时,会走全表扫描。这也是为什么日期类型我们要设置为datetime而不是varchar的原因之一。

总结

通过上述分析,可以总结如下结论:
1.范围查询中,当查询的数据量达到一定范围后,mysql认为全表扫描效率更高,会走全表扫描,而非索引。
2.datetime字段类型的值在查询时也要加引号,否则mysql不会按日期进行处理。
3.日期格式的数据,设置为varchar类型,范围查询走索引还是全表扫描的临界值比datetime类型的查询走索引查询还是全表扫描的临界值低,所以日期类型数据设置为datetime类型,会有更高概率走索引查询。

到此这篇关于记一次Mysql不走日期字段索引的原因的文章就介绍到这了,更多相关Mysql 日期字段索引内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

MySQL 相关文章推荐
MySQL基础(二)
Apr 05 MySQL
MySQL表的增删改查基础教程
Apr 07 MySQL
MySQL sql_mode修改不生效的原因及解决
May 07 MySQL
MySQL COUNT函数的使用与优化
May 10 MySQL
IDEA 链接Mysql数据库并执行查询操作的完整代码
May 20 MySQL
低版本Druid连接池+MySQL驱动8.0导致线程阻塞、性能受限
Jul 01 MySQL
MySQL非空约束(not null)案例讲解
Aug 23 MySQL
MySQL命令无法输入中文问题的解决方式
Aug 30 MySQL
SQL注入篇学习之盲注/宽字节注入
Mar 03 MySQL
MySQL实战记录之如何快速定位慢SQL
Mar 23 MySQL
解决Mysql中的innoDB幻读问题
Apr 29 MySQL
mysql函数之截取字符串的实现
Aug 14 MySQL
Mysql关于数据库是否应该使用外键约束详解说明
Oct 24 #MySQL
MySQL七种JOIN类型小结
MySQL中的引号和反引号的区别与用法详解
SQL实战演练之网上商城数据库商品类别数据操作
Oct 24 #MySQL
为什么MySQL 删除表数据 磁盘空间还一直被占用
mysql中int(3)和int(10)的数值范围是否相同
深入解析MySQL索引数据结构
You might like
关于PHP结束标签的使用细节探讨及联想
2013/03/04 PHP
Ajax和PHP正则表达式验证表单及验证码
2016/09/24 PHP
PHP面向对象之里氏替换原则简单示例
2018/04/08 PHP
jQuery动画animate方法使用介绍
2013/05/06 Javascript
jquery解决客户端跨域访问问题
2015/01/06 Javascript
Javascript 拖拽雏形中的一些问题(逐行分析代码,让你轻松了拖拽的原理)
2015/01/23 Javascript
jQuery基础的工厂函数以及定时器的经典实例分析
2016/05/20 Javascript
深入浅析search 搜索框的写法
2016/08/02 Javascript
AngularJs 利用百度地图API 定位当前位置 获取地址信息
2017/01/18 Javascript
纯JS单页面赛车游戏制作代码分享
2017/03/03 Javascript
关于vuex的学习实践笔记
2017/04/05 Javascript
angular过滤器实现排序功能
2017/06/27 Javascript
浅谈ajax在jquery中的请求和servlet中的响应
2018/01/22 jQuery
通过webpack引入第三方库的方法
2018/07/20 Javascript
jQuery实现鼠标移到某个对象时弹出显示层功能
2018/08/23 jQuery
深入理解JavaScript 中的执行上下文和执行栈
2018/10/23 Javascript
js canvas画布实现高斯模糊效果
2018/11/27 Javascript
详解vue-cli 脚手架 安装
2019/04/16 Javascript
微信小程序如何获取群聊的openGid以及名称详解
2019/07/17 Javascript
layui radio点击事件实现input显示和隐藏的例子
2019/09/02 Javascript
Vue 使用Props属性实现父子组件的动态传值详解
2019/11/13 Javascript
Vue-cli打包后如何本地查看的操作
2020/09/02 Javascript
Vue+Spring Boot简单用户登录(附Demo)
2020/11/12 Javascript
python求斐波那契数列示例分享
2014/02/14 Python
python实现的文件夹清理程序分享
2014/11/22 Python
python爬虫实现中英翻译词典
2019/06/25 Python
Python select及selectors模块概念用法详解
2020/06/22 Python
PyCharm 2020.1版安装破解注册码永久激活(激活到2089年)
2020/09/24 Python
英国旅行箱包和行李箱购物网站:Travel Luggage & Cabin Bags
2019/08/26 全球购物
澳大利亚领先的女帽及配饰公司:Morgan&Taylor
2019/12/01 全球购物
某同学的自我鉴定范文
2013/12/26 职场文书
幼儿园中班上学期评语
2014/04/18 职场文书
花木兰观后感
2015/06/10 职场文书
Python实现的扫码工具居然这么好用!
2021/06/07 Python
15个值得收藏的JavaScript函数
2021/09/15 Javascript
vue自定义右键菜单之全局实现
2022/04/09 Vue.js