MySQL count(*)单条查询比分段查询总耗时更长的原因求解
耗时差异的核心原因
- 缓冲池预热是最核心的影响因素:InnoDB的所有数据读写都需要先将对应的磁盘页加载到内存的缓冲池(Buffer Pool)中,第一次直接执行
select count(*) from result where id < 1000000时,id小于100万对应的所有索引页都还在磁盘上,需要一次性读取大量磁盘页,随机IO开销极高,所以耗时达到4分51秒。 - 分段查询时前几次小范围查询已经完成了大部分数据页的缓存加载:前6次分别查询id<50万、60万直到95万的过程中,已经把id小于95万对应的所有索引页都加载到了缓冲池中,这些页后续查询可以直接从内存读取,不需要再走磁盘IO,所以前6次查询总耗时才不到2秒。最后一次查询id<100万时,只需要加载95万到100万这一小段对应的磁盘页,耗时仅39.66秒,总耗时自然远低于第一次全量冷读的开销。
- 和你提到的cache机制直接相关:这里的缓存包括MySQL层的缓冲池缓存,也包括操作系统层面的页缓存,两次测试的冷热数据状态完全不一样,不具备直接对比的条件。如果你清空MySQL和操作系统缓存之后,先直接执行id<100万的查询,再分段执行查询,就会出现反过来的耗时差异。
- 额外影响因素:单条大范围索引扫描时,更容易触发IO队列拥堵,操作系统的IO调度优先级低,而分段小范围扫描的IO请求更离散,IO调度效率更高,也会一定程度降低总耗时。
内容的提问来源于stack exchange,提问作者Jaden
相关产品推荐
相关产品推荐

