SQL数据库冷热页识别需综合高频+持续访问特征,传统LRU易受扫描干扰;主流方案采用冷热分离双链表(如InnoDB)、访问计数衰减机制及自适应调优策略。

SQL数据库中的冷热页识别,核心在于判断哪些数据页被频繁访问(热页)、哪些长期闲置(冷页),从而优化缓存淘汰策略。传统LRU链表虽简单,但易受扫描类查询、临时热点等干扰,导致热页被误踢出缓冲池。现代数据库普遍对LRU进行演进,不再依赖单一链表,而是引入分层、时序、访问频率等多维信号协同判断。
热页识别不能只看“最近使用”
标准LRU仅记录页面最后一次被访问的时间顺序,一旦发生全表扫描或大范围ORDER BY,大量页面被依次访问,尾部热页就会被挤出——这违背了“热页应常驻内存”的设计目标。真正的热页需满足“高频+持续”,而非“刚被碰过”。因此,单纯靠LRU链表位置无法可靠区分冷热。
主流演进方案:冷热分离双链表(如InnoDB的LRU改良)
以MySQL InnoDB为例,其Buffer Pool LRU链表被逻辑划分为两段:
- Young sublist(热区):存放近期被多次访问、或被预热提升上来的页,新读入页默认不直接进这里
- Old sublist(冷区):新读入页首先进入此区域尾部;只有在冷区被再次访问(即二次命中),才晋升到热区头部
- 淘汰时优先从冷区尾部开始,热区受保护;冷区长度可通过innodb_old_blocks_pct配置(默认37%)
- 另设innodb_old_blocks_time(默认1000ms),防止刚进入冷区就被重复访问而误升热区,需间隔一定时间后再次访问才算数
更进一步:引入访问计数与衰减机制
部分系统(如PostgreSQL的clock-sweep变种、某些NewSQL存储引擎)在页描述符中维护轻量级访问计数器,并叠加时间衰减:
- 每次访问页时,计数器+1;后台线程周期性将所有计数器右移1位(相当于指数衰减)
- 淘汰时按“当前计数值”排序,而非链表位置——高值代表稳定热度,低值或归零代表真实冷页
- 该方式对突发扫描更鲁棒,也能识别长周期业务规律(如每日凌晨报表页自动升温)
结合工作负载特征做自适应调优
静态LRU参数难以适配多样场景。较新的实践是让冷热识别具备反馈能力:
- 监控缓冲池命中率骤降、page relocations激增等信号,自动收紧冷区晋升阈值
- 对已知只读大表(如维表)、日志类历史分区,主动标记为“冷锚页”,禁止进入热区
- 利用查询计划信息,在执行前预判页访问模式(如索引范围扫描 vs 全扫),动态调整加载策略










