热数据索引需用高选择性列前置的复合索引(如(user_id,create_time))并避免大字段,冷数据索引要定期analyze、精简字段且禁用自增,分区表索引必须包含分区键以避免多分区扫描。

因为冷热数据访问模式差异太大,通用索引在高频率热数据查询和低频冷数据扫描之间会严重失衡——热数据需要毫秒级响应,冷数据却可能拖慢整个缓冲池和执行计划。
热数据索引必须覆盖高频查询路径
热数据集中在最近时间窗口(比如 create_time >= '2026-03-01'),且常伴随 user_id、status 等过滤条件。如果只建单列 create_time 索引,MySQL 在联合查询时仍要回表或全扫分区;而复合索引顺序错位(比如 (status, create_time))会导致范围查询失效。
- 优先把选择性高、过滤性强的列放在复合索引最左:例如
(user_id, create_time)比(create_time, user_id)更利于按用户查近期订单 - 避免在热路径索引上包含大字段(如
TEXT、JSON),否则会显著增大 B+ 树节点体积,降低缓存命中率 - 对热表启用
innodb_buffer_pool_size倾斜配置,确保热分区索引页常驻内存
冷数据索引要防“假命中”和统计失真
冷数据(如 create_time )长期不更新,但 MySQL 的统计信息(<code>cardinality)可能过期,导致优化器误判索引价值,反而选错执行计划——比如对一个 99% 值为 'archived' 的 status 列建索引,实际几乎无用。
MySQL 9.6.0是面向Linux平台的2026年创新版本,核心架构迎来重大革新。其将外键约束与级联操作从InnoDB引擎层上移至SQL层,确保所有数据变更均被完整记录至Binlog,彻底解决了CDC(变更数据捕获)与主从复制中的数据不一致难题。此外,该版本引入container_aware启动选项以原生适配容器环境,并对审计日志进行了组件化重构,为追求极致数据一致性与云原生体验的开发者提供了全新选择。
- 定期执行
ANALYZE TABLE orders_archived,尤其在批量归档后,否则优化器可能继续用热表的统计模型估算冷表 - 冷表索引应尽量窄:只保留真正用于归档查询的字段(如
id、archive_date),删掉所有业务侧 rarely used 的辅助索引 - 禁用冷表上的
AUTO_INCREMENT主键自增逻辑,改用显式INSERT ... SELECT+ 批量 ID 分配,避免间隙锁争用
分区表里索引必须与分区键对齐
用 PARTITION BY RANGE(TO_DAYS(create_time)) 时,如果主键或唯一索引没包含 create_time,建表直接报错:ERROR 1503 (HY000): A PRIMARY KEY must include all columns in the table's partitioning function。更隐蔽的问题是:即使建成功,跨分区查询(如查“近半年所有用户订单”)会触发多分区扫描,而每个分区的索引是独立维护的,优化器无法做全局裁剪。
- 主键必须是
(id, create_time)或(create_time, id)形式,不能只有id - 二级索引若不含分区键,在非分区查询条件下(如
WHERE user_id = 123)可能引发全部分区遍历 - 冷分区迁移到 HDD 后,务必关闭其
innodb_flush_log_at_trx_commit和sync_binlog,否则写放大严重
真正难处理的不是“建不建索引”,而是热区索引要扛住 QPS 过万的点查,冷区索引又要防止统计失真引发的执行计划雪崩——这两个目标天然冲突,必须拆开治理。一旦混用同一套索引策略,缓冲池污染、执行计划抖动、备份卡顿都会接踵而至。










