记⼀次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。
mysql下载不了什么原因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 ⽇期字段索引内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论