记一次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 用户权限管理实现
May 25 MySQL
MySQL中使用or、in与union all在查询命令下的效率对比
May 26 MySQL
Navicat连接MySQL错误描述分析
Jun 02 MySQL
MySQL Shell import_table数据导入的实现
Aug 07 MySQL
千万级用户系统SQL调优实战分享
Mar 03 MySQL
Mysql外键约束的创建与删除的使用
Mar 03 MySQL
MySQL学习之基础命令实操总结
Mar 19 MySQL
WINDOWS 64位 下安装配置mysql8.0.25最详细的教程
Mar 22 MySQL
mysql的单列多值存储实例详解
Apr 05 MySQL
Mysql 数据库中的 redo log 和 binlog 写入策略
Apr 26 MySQL
MySQL一劳永逸永久支持输入中文的方法实例
Aug 05 MySQL
SQL中去除重复数据的几种方法汇总(窗口函数对数据去重)
May 08 MySQL
Mysql关于数据库是否应该使用外键约束详解说明
Oct 24 #MySQL
MySQL七种JOIN类型小结
MySQL中的引号和反引号的区别与用法详解
SQL实战演练之网上商城数据库商品类别数据操作
Oct 24 #MySQL
为什么MySQL 删除表数据 磁盘空间还一直被占用
mysql中int(3)和int(10)的数值范围是否相同
深入解析MySQL索引数据结构
You might like
php 广告调用类代码(支持Flash调用)
2011/08/11 PHP
逆序二维数组插入一元素的php代码
2012/06/08 PHP
浅析SVN常见问题及解决方法
2013/06/21 PHP
Yii CGridView用法实例详解
2016/07/12 PHP
怎么用javascript进行拖拽
2006/07/20 Javascript
JavaScript 学习笔记(五)
2009/12/31 Javascript
原生Js与jquery的多组处理, 仅展开一个区块的折叠效果
2011/01/09 Javascript
对xmlHttp对象的理解
2011/01/17 Javascript
jquery.boxy弹出框(后隔N秒后自动隐藏/自动跳转)
2013/01/15 Javascript
nodejs文件操作模块FS(File System)常用函数简明总结
2014/06/05 NodeJs
jQuery中toggleClass()方法用法实例
2015/01/05 Javascript
使用基于Node.js的构建工具Grunt来发布ASP.NET MVC项目
2016/02/15 Javascript
理解javascript定时器中的单线程
2016/02/23 Javascript
js获取页面及个元素高度、宽度的代码
2016/04/26 Javascript
AngularJS基础 ng-model-options 指令简单示例
2016/08/02 Javascript
AngularJS基础 ng-readonly 指令简单示例
2016/08/02 Javascript
Vue 兄弟组件通信的方法(不使用Vuex)
2017/10/26 Javascript
Vue组件的使用教程详解
2018/01/05 Javascript
jQuery代码优化方法总结
2018/01/29 jQuery
bootstrap里bootstrap动态加载下拉框的实例讲解
2018/08/10 Javascript
React Router V4使用指南(精讲)
2018/09/17 Javascript
vue最简单的前后端交互示例详解
2018/10/11 Javascript
Node.js之删除文件夹(含递归删除)代码实例
2019/09/09 Javascript
jquery实现两个div中的元素相互拖动的方法分析
2020/04/05 jQuery
JavaScript 监听组合按键思路及代码实现
2020/07/28 Javascript
原生js生成图片验证码
2020/10/11 Javascript
详细介绍Python中的偏函数
2015/04/27 Python
Python简单实现词云图代码及步骤解析
2020/06/04 Python
台湾母婴用品购物网站:Infant婴之房
2018/06/15 全球购物
新品发布会策划方案
2014/06/08 职场文书
英语专业自荐书
2014/06/13 职场文书
考研英语复习计划
2015/01/19 职场文书
现货白银电话营销话术
2015/05/29 职场文书
pytest配置文件pytest.ini的详细使用
2021/04/17 Python
Spring boot应用启动后首次访问很慢的解决方案
2021/06/23 Java/Android
IIS服务器中设置HTTP重定向访问HTTPS
2022/04/29 Servers