记一次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的join buffer原理
Apr 29 MySQL
MySQL 隔离数据列和前缀索引的使用总结
May 14 MySQL
简单了解 MySQL 中相关的锁
May 25 MySQL
MySQL8.0的WITH查询详情
Aug 30 MySQL
Mysql实现简易版搜索引擎的示例代码
Aug 30 MySQL
记一次Mysql不走日期字段索引的原因小结
Oct 24 MySQL
一文搞懂MySQL索引页结构
Feb 28 MySQL
一条慢SQL语句引发的改造之路
Mar 16 MySQL
Pycharm远程调试和MySQL数据库授权问题
Mar 18 MySQL
MySQL创建表操作命令分享
Mar 25 MySQL
为什么MySQL8新特性会修改自增主键属性
Apr 18 MySQL
MySQL transaction事务安全示例讲解
Jun 21 MySQL
Mysql关于数据库是否应该使用外键约束详解说明
Oct 24 #MySQL
MySQL七种JOIN类型小结
MySQL中的引号和反引号的区别与用法详解
SQL实战演练之网上商城数据库商品类别数据操作
Oct 24 #MySQL
为什么MySQL 删除表数据 磁盘空间还一直被占用
mysql中int(3)和int(10)的数值范围是否相同
深入解析MySQL索引数据结构
You might like
windows7下安装php的php-ssh2扩展教程
2014/07/04 PHP
详解WordPress中调用评论模板和循环输出评论的PHP函数
2016/01/05 PHP
symfony2.4的twig中date用法分析
2016/03/18 PHP
thinkPHP自动验证机制详解
2016/12/05 PHP
phalcon model在插入或更新时会自动验证非空字段的解决办法
2016/12/29 PHP
PHP编译configure时常见错误的总结
2017/08/17 PHP
PHP htmlentities()函数用法讲解
2019/02/25 PHP
PHP超低内存遍历目录文件和读取超大文件的方法
2019/05/01 PHP
巧妙破除网页右键禁用的十大绝招
2006/08/12 Javascript
URI、URL和URN之间的区别与联系
2006/12/20 Javascript
浅析jQuery1.8的几个小变化
2013/12/10 Javascript
JavaScript参数个数可变的函数举例说明
2014/10/10 Javascript
jquery pagination插件动态分页实例(Bootstrap分页)
2016/12/23 Javascript
jquery append与appendTo方法比较
2017/05/24 jQuery
JS实现的简单标签点击切换功能示例
2017/09/21 Javascript
微信小程序BindTap快速连续点击目标页面跳转多次问题处理
2019/04/08 Javascript
JS实现导航栏楼层特效
2020/01/01 Javascript
vue-iview动态新增和删除的方法
2020/06/17 Javascript
js闭包和垃圾回收机制示例详解
2021/03/01 Javascript
[48:47]VGJ.S vs NB 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
Python下的Softmax回归函数的实现方法(推荐)
2017/01/26 Python
python实现自动发送邮件发送多人、群发、多附件的示例
2018/01/23 Python
对python实时得到鼠标位置的示例讲解
2018/10/14 Python
浅谈Django+Gunicorn+Nginx部署之路
2019/09/11 Python
python机器学习库xgboost的使用
2020/01/20 Python
Python TestSuite生成测试报告过程解析
2020/07/23 Python
python使用布隆过滤器的实现示例
2020/08/20 Python
小结Python的反射机制
2020/09/28 Python
巧克力领导品牌瑞士莲美国官网:Lindt Chocolate美国
2016/08/25 全球购物
美国本地交易和折扣网站:LocalFlavor.com
2017/10/26 全球购物
泰国办公用品购物网站:OfficeMate
2018/02/04 全球购物
利用异或运算实现两个无符号数的加法运算
2013/12/20 面试题
可以使用抽象函数重写基类中的虚函数吗
2013/06/02 面试题
2014大学生全国两会学习心得体会
2014/03/13 职场文书
施工员岗位职责
2014/03/16 职场文书
Python爬虫中urllib3与urllib的区别是什么
2021/07/21 Python