You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails项目MySQL的created_at字段索引未被查询使用问题咨询

问题原因

这个场景下索引没有被使用,不是索引创建失败或者失效,而是MySQL查询优化器基于查询成本估算做出的主动选择,核心逻辑如下:

  • 二级索引使用存在回表开销:你执行的是SELECT *查询,要返回表的所有字段。index_cache_syncs_on_created_at是普通二级索引,索引叶子节点只存储created_at和主键id的值,如果走这个索引,需要先从二级索引树筛选出符合条件的主键id,再回到主键聚簇索引查找整行数据,这个过程产生的随机IO开销很高。
  • 符合条件的记录占比过高,触发优化器的放弃索引逻辑:从你提供的执行计划看,表总预估行数是93651,你查询的是created_at < 当前时间减1小时的记录,说明1小时前产生的历史数据占了表总数据的绝大多数。MySQL优化器的通用判断规则是:如果查询需要返回的记录数超过表总记录数的20%~30%,走二级索引+回表的成本会高于直接全表扫描(全表扫描是顺序IO,大数量下效率远高于大量随机回表IO),因此会主动选择全表扫描,即使索引在possible_keys列表里也不会被选用。
验证方式

你可以通过两个简单的测试验证这个逻辑:

  1. 收紧查询条件,降低符合条件的记录占比,比如把条件改成created_at < 30天前,此时符合条件的记录占比极低,再查看执行计划就会发现该索引被正常使用。
  2. 改写查询为覆盖索引查询,避免回表,比如只查询id和created_at字段(这两个字段都在二级索引树里存储,不需要回表):
CacheSync.select(:id, :created_at).where("created_at < ?", 1.hour.ago).explain

此时执行计划会显示走index_cache_syncs_on_created_at索引,因为省去了回表的随机IO开销,走索引的成本低于全表扫描。

补充说明

如果确认是统计信息偏差导致优化器误判(比如实际符合条件的记录占比很低,但优化器预估很高),可以执行ANALYZE TABLE cache_syncs;刷新表的统计信息,让优化器拿到更准确的基数数据重新判断。但从你当前给出的查询条件和数据量看,不属于统计信息偏差的问题,是优化器的正常选择。

内容的提问来源于stack exchange,提问作者user1130176

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 17:27:41