背景我使用SQLite存储大约10M条目,每个条目的大小约为1Kb。我使用多个并行线程一次以大约100K个条目的形式读回这些数据。读取和写入不是并行的,所有写入都是在开始读取之前完成的。
问题我遇到太多磁盘读取。每秒大约3k读取正在发生,我在这3k读取中只读取30Kb数据(因此每个磁盘读取大约100个字节)。结果,我看到一个非常可怕的表现(阅读数据需要大约30分钟)
题
实现细节我使用SQlite和Java,我的应用程序在linux上运行。 JDBC库是https://github.com/xerial/sqlite-jdbc(版本3.20.1)。
P.S我已经构建了必要的索引,并验证没有进行表扫描(使用Explain Query planner)
当您使用索引搜索数据时,数据库首先在索引中查找值,然后转到相应的表行以读取所有其他列。
除非表行恰好以与索引中的值相同的顺序存储,否则每个这样的表读取必须转到不同的页面。
仅当搜索减少行数时,索引才会加快搜索速度。如果你要读取所有(或大部分)行,那么表扫描会快得多。
只有当磁盘可以实际处理额外的I / O时,并行读取才会更有效。在旋转磁盘上,额外的搜索只会让事情变得更糟。
(SQLite尝试避免存储临时结果。当您单步执行游标时,结果行会尽可能快地计算。)