想象一下,我们有一个包含 1 亿行和 80 GB 大小的表。
每行都有文本列和相乘的整数列。
我们将 Innodb_buffer_pool_size 设置为 40G
我执行这个查询:
select text,id,like_count from example where time > 'xxx-xx-xx' and time < 'xxx-xx-xx'
所以如果这个查询需要读取 50G 的数据文件(因为查询)并移动到缓冲池。我想知道缓冲池如何处理这些数据。
因为我们将缓冲池设置为 40G,但查询需要 50G 来处理它。
您的场景听起来完全像 mysqldump 将执行的操作:将每个数据和索引页推出 InnoDB 缓冲池。你可以看到是这种情况,因为当 mysqldump 正在进行时,processlist 将有类似
SELECT /*!N SQL_NO_CACHE */ from ...
. 请参阅 MySQL 慢查询日志中 mysqldump 的 SELECT 外观示例- SELECT /*!N SQL_NO_CACHE */任何全表扫描都会将表中的每个数据页推送到缓冲池中,从而导致缓冲池中的每个旧页都被逐出,这是有道理的。如果将 50G 的数据页推送到 40GB 的缓冲池中,您的缓冲池将包含该表的最后 80%,因为前 20% 会被推送到缓冲池中,然后被直接推出。我大约 4 个月前提到过(请参阅我的旧帖子Is it safe to run parallel innodb single-transaction dumps of individual tables?)
建议
如果你的目标是让缓冲池的内容在一个巨大的查询之前和之后看起来一样,那么你只能做一件事:将缓冲池的映射转储到磁盘,运行你的大查询,并从地图。
请参阅有关这些选项的 MySQL 文档