MySql innodb_buffer_pool_size 缓存数据详细信息
MySql innodb_buffer_pool_size cached data details
innodb_buffer_pool_size - 此参数用于定义分配给经常使用的缓存数据的内存。我的架构中有许多 table,其中有数百万条记录。当我检查缓冲区缓存使用情况时,它占用了所有分配的内存。
是否有任何方法可以识别正在缓存的 table 或索引是什么以及哪些缓存命中率高于其他缓存命中率?一旦我最终得到它,我可能会从这些数据中删除一些数据。
如果 table 包含 1000 条记录并且如果在主键条件下执行查询。它是否将整个索引缓存在缓冲区缓存中?
如果上述 none 是解决方案,我可以减小 MySql 缓冲区的大小。如果有任何其他方法可以减少 MySql 进程的内存使用量,因为我想分配给其他进程。
没有
“缓存”以块为基础工作,而不是整个 table,也不是整个索引。
- table 的数据组织在一个 16KB 块的 BTree 中。
- table 的每个辅助
INDEX
组织在 16KB 块的 BTree 中。
- 每个块都独立于其他块加载到 buffer_pool 并从 buffer_pool 中弹出。
- 缓存(大致)是“最近最少组织的”。 (再次强调,“块”是单位,而不是table或索引。)
- BTree 的根节点被频繁使用,因此它倾向于留在 buffer_pool 中。您可能会发现自重新启动以来触摸的每个 table 的 that 块仍在 buffer_pool 中。然而,许多其他区块可能来来去去。
针对您的问题:
- 有什么方法可以识别正在缓存的 table 或索引是什么以及哪些缓存命中率高于其他索引? ——不容易。即使你有这些信息,它也没有用(见上文)。
- 一旦我终于得到它,我可能会从这些数据中删除一些数据。 -- 不行,就算可以,也没多大用处
- 如果 table 包含 1000 条记录并且如果在主键条件下执行查询。 -- 由于数据是按 PK 排序的,因此这 1000 行将在连续的块中“聚集”在一起。我估计只有大约 10 个街区。
- 是否在缓冲区高速缓存中缓存整个索引? -- 如上所述,只能逐块。
更多注意事项:
- 一个简单的经验法则是一个 BTree 块包含 100 个项目。
- 这意味着一百万行的 BTree(table 或索引)大约有 3 (100^3 = 1M) 层深。并且会有大约10000(1M/100)个叶子块。
- (继续 1M 行 table)通过 PK 获取 1 行会将大约 3 个块带入缓存。
- 如果一个块不在缓存中,它需要弹出一个'old'(LRU)块来腾出空间,然后进行磁盘读取(慢)。如果块已经在缓存中,则不需要 I/O。
- 通过辅助键获取 1 行将需要大约 6 个块。这是 3 个用于向下钻取二级索引的 BTree,然后还有 3 个用于在数据的 BTree 中查找记录。 (PK 隐含在二级索引的“行”中。)
- 通过主键获取1000连续行(例如,通过'range'查询):3 + 10块需要在缓存中,因此 0 到 13 次磁盘读取。
- 通过二级索引获取1000连续行(例如,通过'range'查询):3 + 10索引中的块,然后是数据中的 3 个块,再加上 10 到 1000 个块。
好吧,我啰嗦了很久。接下来您想知道什么?
innodb_buffer_pool_size - 此参数用于定义分配给经常使用的缓存数据的内存。我的架构中有许多 table,其中有数百万条记录。当我检查缓冲区缓存使用情况时,它占用了所有分配的内存。
是否有任何方法可以识别正在缓存的 table 或索引是什么以及哪些缓存命中率高于其他缓存命中率?一旦我最终得到它,我可能会从这些数据中删除一些数据。
如果 table 包含 1000 条记录并且如果在主键条件下执行查询。它是否将整个索引缓存在缓冲区缓存中?
如果上述 none 是解决方案,我可以减小 MySql 缓冲区的大小。如果有任何其他方法可以减少 MySql 进程的内存使用量,因为我想分配给其他进程。
没有
“缓存”以块为基础工作,而不是整个 table,也不是整个索引。
- table 的数据组织在一个 16KB 块的 BTree 中。
- table 的每个辅助
INDEX
组织在 16KB 块的 BTree 中。 - 每个块都独立于其他块加载到 buffer_pool 并从 buffer_pool 中弹出。
- 缓存(大致)是“最近最少组织的”。 (再次强调,“块”是单位,而不是table或索引。)
- BTree 的根节点被频繁使用,因此它倾向于留在 buffer_pool 中。您可能会发现自重新启动以来触摸的每个 table 的 that 块仍在 buffer_pool 中。然而,许多其他区块可能来来去去。
针对您的问题:
- 有什么方法可以识别正在缓存的 table 或索引是什么以及哪些缓存命中率高于其他索引? ——不容易。即使你有这些信息,它也没有用(见上文)。
- 一旦我终于得到它,我可能会从这些数据中删除一些数据。 -- 不行,就算可以,也没多大用处
- 如果 table 包含 1000 条记录并且如果在主键条件下执行查询。 -- 由于数据是按 PK 排序的,因此这 1000 行将在连续的块中“聚集”在一起。我估计只有大约 10 个街区。
- 是否在缓冲区高速缓存中缓存整个索引? -- 如上所述,只能逐块。
更多注意事项:
- 一个简单的经验法则是一个 BTree 块包含 100 个项目。
- 这意味着一百万行的 BTree(table 或索引)大约有 3 (100^3 = 1M) 层深。并且会有大约10000(1M/100)个叶子块。
- (继续 1M 行 table)通过 PK 获取 1 行会将大约 3 个块带入缓存。
- 如果一个块不在缓存中,它需要弹出一个'old'(LRU)块来腾出空间,然后进行磁盘读取(慢)。如果块已经在缓存中,则不需要 I/O。
- 通过辅助键获取 1 行将需要大约 6 个块。这是 3 个用于向下钻取二级索引的 BTree,然后还有 3 个用于在数据的 BTree 中查找记录。 (PK 隐含在二级索引的“行”中。)
- 通过主键获取1000连续行(例如,通过'range'查询):3 + 10块需要在缓存中,因此 0 到 13 次磁盘读取。
- 通过二级索引获取1000连续行(例如,通过'range'查询):3 + 10索引中的块,然后是数据中的 3 个块,再加上 10 到 1000 个块。
好吧,我啰嗦了很久。接下来您想知道什么?