冷热数据分离的核心是按访问频次与业务语义划分,热数据存近期高频明细,冷数据归档历史低频记录;通过表分区、归档表、读写路由实现物理拆分,并辅以汇总表、精准索引和资源隔离保障性能与可用性。

冷热数据分离的核心逻辑
热数据是近期频繁访问、参与计算的记录,比如最近3个月的订单;冷数据是历史归档、极少查询的记录,比如3年前的销售日志。分离不是简单按时间切分,而是围绕“访问频次+业务语义”设计——用户查近30天订单要秒出,查5年前报表可以接受几秒延迟,这才是优化的出发点。
物理层面怎么拆:表分区 + 归档表 + 读写路由
直接删旧数据不可取,归档才是正解。推荐三步走:
- 按时间分区建热表:用 RANGE 分区(如 MySQL 的 PARTITION BY RANGE (TO_DAYS(create_time))),把最近12个月数据按月切片,查询时自动剪枝,避免全表扫描
- 冷数据迁入独立归档库/表:用 INSERT … SELECT + DROP PARTITION 配合完成迁移,归档表可启用压缩(如 InnoDB ROW_FORMAT=COMPRESSED)节省空间
- 应用层路由查询:在DAO或中间件中识别查询时间范围,近3个月走热库,超期走冷库;不依赖数据库自动判断,可控性更强
查询层优化:物化视图 + 汇总表替代高频聚合
报表常跑 COUNT/SUM/GROUP BY,但冷表上实时聚合很慢。与其反复扫千万级历史数据,不如提前算好:
- 每天凌晨对冷数据生成日粒度汇总表(如 sales_daily_summary),字段精简到报表所需维度+指标
- 热数据仍保留明细,但只存最近7天;7–90天用小时级汇总表支撑趋势分析
- BI工具连接时,SQL自动重写为查汇总表——可用视图或Query Rewrite插件(如MySQL 8.0的Query Rewrite Plugin)实现透明替换
索引与统计信息不能忽略
冷表虽不常写,但查询条件可能变(比如突然要按地区+年份查5年前数据)。必须保障:
- 冷表保留必要联合索引,例如 (region, year, status),覆盖典型报表WHERE条件
- 定期 ANALYZE TABLE 更新统计信息,避免优化器误判走错执行计划
- 关闭冷表的自动统计更新(如 innodb_stats_auto_recalc=OFF),改用定时任务手动触发,防止归档期间影响热库性能
别忘了冷数据的可用性兜底
归档不是丢弃。用户偶尔要查原始单据,就得能快速捞出来:
- 冷表保留主键和关键业务索引,禁用全文、GIS等重型索引
- 归档库单独部署,与热库隔离资源(CPU/内存/IOPS),避免报表导出拖垮在线交易
- 提供自助式冷数据查询入口(带时间范围强校验),返回结果限制条数并加超时(如30秒),防误操作扫全量










