Marcus Asked: 2017-07-16 06:57:14 +0800 CST2017-07-16 06:57:14 +0800 CST 2017-07-16 06:57:14 +0800 CST 如果查询读取的页面多于 InnoDB 缓冲区可以容纳的页面,是否所有以前的页面都被驱逐了? 772 如果我在 InnoDB 缓冲区中有一些(热)页面,并且我执行了一个查询,该查询读取的数据量大于缓冲区本身,是否一定要驱逐热页面? mysql innodb 1 个回答 Voted Best Answer joanolo 2017-07-16T07:06:13+08:002017-07-16T07:06:13+08:00 根据MySQL 5.7 参考手册 - InnoDB 缓冲池 InnoDB 使用最近最少使用 (LRU) 算法的变体将缓冲池作为列表进行管理。当需要空间将新页面添加到池中时,InnoDB 会驱逐最近最少使用的页面并将新页面添加到列表的中间。这种“中点插入策略”将列表视为两个子列表: 在头部,最近访问的“新”(或“年轻”)页面的子列表。 在尾部,最近访问较少的“旧”页面的子列表。 该算法将查询大量使用的页面保留在新的子列表中。旧子列表包含较少使用的页面;这些页面是驱逐的候选者。 (强调我的) 我认为这就是您正在寻找的答案。并非所有页面都被逐出,它们一次被逐出一个,并且每次只会逐出旧页面。显然,如果查询需要可用池的两倍(或更多),最终所有页面都可能被逐出,具体取决于它们的使用频率。 我会说B+ 树根附近的所有页面(用于索引和表的聚类方式)将比其他页面更频繁地使用,因此,它们不太可能被驱逐。然而,在某些只有大量全表扫描的情况下,(可能)只通过一次页面,最终可能会淹没和驱逐所有热门页面。我认为这不太可能,但理论上是可能的。
根据MySQL 5.7 参考手册 - InnoDB 缓冲池
(强调我的)
我认为这就是您正在寻找的答案。并非所有页面都被逐出,它们一次被逐出一个,并且每次只会逐出旧页面。显然,如果查询需要可用池的两倍(或更多),最终所有页面都可能被逐出,具体取决于它们的使用频率。
我会说B+ 树根附近的所有页面(用于索引和表的聚类方式)将比其他页面更频繁地使用,因此,它们不太可能被驱逐。然而,在某些只有大量全表扫描的情况下,(可能)只通过一次页面,最终可能会淹没和驱逐所有热门页面。我认为这不太可能,但理论上是可能的。