知识卡片

冷热数据混在同一物理页,会让整页被误判为"热"

普通读书笔记卡

内容

[[工作集概念缓存单位放大让聚簇索引选择影响缓存效率]]说明了缓存是按 “页”这个物理单位工作的,这里补上一个直接后果:如果活跃(热)和不活跃 (冷)的数据混在同一张表、恰好又落进了同一个物理页里,InnoDB是按页 整体判断和缓存”热度”的,只要这一页里有任何一行被访问,整页都会被当作 热数据留在缓冲池里。举例来说,一个页能存100个用户的数据,其中只有 10%是活跃用户,但因为这10%的访问,其余90%本不该被缓存的冷数据也会 跟着一起占用缓冲池空间——缓存空间的浪费不是发生在”数据本身该不该缓存” 这个判断上,而是发生在”缓存的最小粒度是页、而不是行”这个物理约束上。 解决办法不是让InnoDB变聪明去识别页内的行级热度(这在B-Tree存储引擎的 物理布局下做不到),而是从schema设计上主动把冷热数据分离到不同的表, 让它们各自聚集进各自的物理页,比如把users表拆成active_usersinactive_users两张表;如果数据按时间自然变热变冷(比如博客系统里 最近一周的文章和评论是访问热点),也可以按时间维度做数据分区,让最新 数据集中落在少数几页里,方便整体常驻内存。这是”缓存单位放大效应”给 schema设计的一条具体启发:表结构的物理布局本身就是缓存效率的一个 可调设计维度,不是只有加内存这一条路。

参考来源

- 位置:《高性能MySQL:第3版》第11章"可扩展的MySQL"11.2.7节"向内 扩展"(源文件:_epub-src/OEBPS/Text/part0018.xhtml) - 结论依据:原文明确"如果用的是InnoDB,每次缓存一页,而一页能存储 100个用户,但只有10%是活跃的,那么这时候InnoDB可能认为所有的页 都是'热'的——因此每个'热'页的90%将被浪费掉。将其拆成两个表可以 明显改善内存利用率",直接说明冷热数据混页导致缓存浪费的机制及拆表 这一具体解决办法。 - 原始内容:如果用的是InnoDB,每次缓存一页,而一页能存储100个用户, 但只有10%是活跃的,那么这时候InnoDB可能认为所有的页都是"热"的—— 因此每个"热"页的90%将被浪费掉。