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

 更新时间:2021年10月22日 11:06:27   作者:敲代码的小小酥  
本文主要介绍了记一次Mysql不走日期字段索引的原因,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

背景

在一个表中,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语句分析结果为全表扫描:

在这里插入图片描述

我们把查询条件改为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会使用索引查询。
全表的数据量为19714条数据,也就是说当2525/19714=13%的时候,mysql走索引查询。当3910/19714=20%的时候,mysql走全表扫描。

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

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

在这里插入图片描述
可见,去掉引号后,又成了全表扫描。所以说,不管字段类型是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';

在这里插入图片描述

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

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

在这里插入图片描述

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 too many connections错误的原因及解决

    MySQL too many connections错误的原因及解决

    这篇文章主要介绍了MySQL too many connections错误的原因及解决,帮助大家更好的理解和学习使用MySQL,感兴趣的朋友可以了解下
    2021-03-03
  • mysql 8.0.22 安装配置方法图文教程

    mysql 8.0.22 安装配置方法图文教程

    这篇文章主要为大家详细介绍了mysql 8.0.22 安装配置方法图文教程,文中安装步骤介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-10-10
  • MySQL派生表合并优化的原理和实现过程

    MySQL派生表合并优化的原理和实现过程

    本文从一个案例出发梳理了MySQL派生表合并优化的流程实现和优化原理,并对优化前后同一条SQL语句在代码层面的类实例映射关系进行了对比,这篇文章主要介绍了MySQL派生表合并优化的原理和实现,需要的朋友可以参考下
    2024-07-07
  • 详解MySql中InnoDB存储引擎中的各种锁

    详解MySql中InnoDB存储引擎中的各种锁

    本文主要介绍了详解MySql中InnoDB存储引擎中的各种锁,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • MySQL Prepared Statement 预处理的操作方法

    MySQL Prepared Statement 预处理的操作方法

    预处理语句是一种在数据库管理系统中使用的编程概念,用于执行对数据库进行操作的 SQL 语句,这篇文章主要介绍了MySQL Prepared Statement 预处理 ,需要的朋友可以参考下
    2024-08-08
  • mysql实现不用密码登录的实例方法

    mysql实现不用密码登录的实例方法

    在本篇文章里小编给大家整理的是一篇关于mysql实现不用密码登录的实例方法,有需要的朋友们可以学习参考下。
    2020-08-08
  • MySQL数据库的触发器和事务

    MySQL数据库的触发器和事务

    这篇文章主要介绍了MySQL数据库的触发器和事务,触发器是SQL server提供给程序员和数据分析员来保证数据完整性的一种方法,它是与表事件相关的特殊的存储过程,是由事件来触发
    2022-08-08
  • Centos下 修改mysql密码的方法

    Centos下 修改mysql密码的方法

    这篇文章主要介绍了Centos下 修改mysql密码的方法,需要的朋友可以参考下
    2017-02-02
  • mysql 5.7.27 安装配置方法图文教程

    mysql 5.7.27 安装配置方法图文教程

    这篇文章主要为大家详细介绍了mysql 5.7.27 安装配置方法图文教程,文中安装步骤介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-10-10
  • mysql安装报错unknown variable mysqlx_port=0.0

    mysql安装报错unknown variable mysqlx_port=0.0

    本文主要介绍了mysql安装报错unknown variable mysqlx_port=0.0,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-06-06

最新评论