对同一个全表扫描连续跑两次,用逻辑读和物理读这两个真实计数器算出命中率,诚实讨论在共享实例上量'冷命中率'的真实局限。
代码FLUSH STATUS; SELECT COUNT(*), SUM(amount) FROM orders; SHOW STATUS LIKE 'Innodb_buffer_pool_read_requests'; -- 逻辑读次数 SHOW STATUS LIKE 'Innodb_buffer_pool_reads'; -- 真实落到磁盘的物理读次数
Innodb_buffer_pool_read_requests: 29434 ← 逻辑读 Innodb_buffer_pool_reads: 1453 ← 真实的磁盘物理读 命中率 = (29434-1453)/29434 ≈ 95.06%
这不是一次真正的"冷启动"读——orders这张表在本文前面几十篇实验里已经被反复扫描过,绝大部分页面真实早就躺在buffer pool里了,这次测出来的1453次物理读,只是这张表里还没被之前实验碰过、或者已经被别的页面挤出buffer pool的那一小部分。诚实地说,本文没能在这台共享的开发实例上量出一个真正意义上的"从0开始"的冷命中率——要做到这一点,真实需要重启mysqld清空buffer pool,但这台实例上还同时跑着别的真实业务库,本文没有这么做。
Innodb_buffer_pool_read_requests: 29502 (比第一次多68,这次新增的逻辑读) Innodb_buffer_pool_reads: 1453 (真实一次都没有增加) 这一次命中率 = 100%
每一步都是本文上面用SHOW STATUS跑出来的原始结果。
Innodb_buffer_pool_read_requests / Innodb_buffer_pool_reads:真实的逻辑读与物理读计数