为何先执行无排序SQL查询再执行带排序查询,总耗时远低于单独执行带排序查询?
问题原因分析
核心原因:磁盘IO开销的大幅减少
SQLite会把从磁盘读取的数据页暂存在内存缓存中。单独执行清缓存后的Query B时,需要先从磁盘读取4张表的所有相关数据——这部分是耗时的核心(比如单独Query B的20秒里,绝大多数时间都消耗在磁盘IO上),之后还要执行ORDER BY排序操作。但先执行Query A后,它已经把Query B需要的所有数据页加载到了内存缓存里,Query B再执行时完全无需再从磁盘读取数据,直接复用缓存内容,省掉了最耗时的磁盘读取步骤。ORDER BY的开销被拆分,未叠加磁盘IO成本
单独执行Query B时,磁盘读数据的时间与排序时间是叠加的:比如读数据耗时14秒,排序耗时6秒,总计20秒。而先执行Query A(6秒,主要是磁盘读数据+基础查询逻辑),再执行Query B时,仅需在已缓存的内存数据上完成排序(约0.5秒),加上少量查询逻辑的开销,总耗时约6.5秒,两次查询的总耗时自然远低于单独执行Query B的20秒。SQLite内存缓存的复用逻辑
只要缓存未被手动清理(比如未执行PRAGMA cache_size = 0)或进程未重启,之前查询加载到内存的数据页会被后续同数据范围的查询复用。由于Query A和Query B针对的是同4张表的相同数据范围,Query A加载的缓存完全可以被Query B利用,避免了重复的磁盘读取操作。
内容的提问来源于stack exchange,提问作者Nox
相关产品推荐
相关产品推荐

