网站首页 > 技术文章 正文
我们都知道在数据库查询时,索引可以极大地提高查询效率。通常在使用的时候,都会针对频繁查询的关键字段建立索引。
比如,当以交易日期(trans_date)来查询交易记录时,通常会对该字段添加索引,以便在大量数据的情况下提升查询效率。
针对trans_date字段,创建union_idx_query索引,那么在下面以trans_date为查询条件的语句中,毫无疑问是会走索引的:
select count(1) from A; // 40000
EXPLAIN select * from A where trans_date = '20220222';
索引1
此时,我们会想当然地以为,只要创建了索引,其他情况的使用同样会走索引。比如下面的查询语句:
select count(1) from t_trans_log_info where trans_date > '20220122'; //11200
EXPLAIN select * from t_trans_log_info where trans_date > '20220122';
上面的查询语句使用了”>“来进行范围的查询,而且trans_date字段同样创建了索引,那么上述SQL语句是否会走索引呢?答案是不一定。
索引2
explain上述SQL语句,发现没有走索引,全表扫描。
但当换一个查询参数时:
select count(1) from t_trans_log_info where trans_date > '20220222'; //1120
EXPLAIN select * from t_trans_log_info where trans_date > '20120222';
explain的结果显示走索引:
索引3
为什么同样的查询语句,只是查询的参数值不同,却会出现一个走索引,一个不走索引的情况呢?
答案很简单:上述索引失效是因为DBMS发现全表扫描比走索引效率更高,因此就放弃了走索引。
也就是说,当Mysql发现通过索引扫描的行记录数超过全表的10%-30%时,优化器可能会放弃走索引,自动变成全表扫描。某些场景下即便强制SQL语句走索引,也同样会失效。
类似的问题,在进行范围查询(比如>、< 、>=、<=、in等条件)时往往会出现上述情况,而上面提到的临界值根据场景不同也会有所不同。
所以,如果你在项目中采用了上述方式的查询,又希望它能够走索引,就需要特别注意了。通常需要添加一些其他的限制条件或用其他方式来保证索引的有效性。
- 上一篇: 京东面试:说说MySQL的架构体系
- 下一篇: 云数据库ClickHouse二级索引 - 最佳实践
猜你喜欢
- 2024-11-18 MySQL中多表联合查询与子查询的这些区别,你可能不知道
- 2024-11-18 Mysql实战总结&面试20问
- 2024-11-18 MySQL的备份与还原,非常规备份,全量备份,增量备份
- 2024-11-18 MySQL范围查询与优化
- 2024-11-18 云数据库ClickHouse二级索引 - 最佳实践
- 2024-11-18 分享一个小技巧——mysql统一处理创建时间和更新时间
- 2024-11-18 京东面试:说说MySQL的架构体系
- 2024-11-18 C#生态下的又一个佳作——FreeSql (O/RM)
- 2024-11-18 MySQL:count(*)为什么这么慢?
- 2024-11-18 与 MySQL 建立连接
- 最近发表
- 标签列表
-
- cmd/c (57)
- c++中::是什么意思 (57)
- sqlset (59)
- ps可以打开pdf格式吗 (58)
- phprequire_once (61)
- localstorage.removeitem (74)
- routermode (59)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- log.warn (60)
- cannotinstantiatethetype (62)
- js数组插入 (83)
- resttemplateokhttp (59)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- reader.onload (61)
- outofmemoryerror是什么意思 (64)
- flask文件上传 (63)
- eacces (67)
- 查看mysql是否启动 (70)
- java是值传递还是引用传递 (58)
- 无效的列索引 (74)