背景我正在使用SQLite存储大约1000万个条目,每个条目的大小约为1Kb。我使用多个并行线程一次读回大约10万个条目的数据。读取和写入不是并行进行的,并且所有写入都在开始读取之前完成。
问题我遇到了太多的磁盘读取。每秒大约发生3k读取,而在这3k读取中,我仅读取30Kb数据(因此,每个磁盘读取大约100字节)。结果,我看到了一个非常糟糕的表现(读取数据大约需要30分钟)
问题
实施细节我将SQlite与Java结合使用,而我的应用程序则在Linux上运行。 JDBC库为https://github.com/xerial/sqlite-jdbc(版本3.20.1)。
PS 我已经建立了必要的索引,并确认没有正在进行表扫描(使用Explain Query Planner)
答案 0 :(得分:1)
当您使用索引搜索数据时,数据库首先在索引中查找值,然后转到相应的表行以读取所有其他列。
除非表行碰巧以与索引中的值相同的顺序存储,否则每次读取的此类表都必须转到不同的页面。
仅当搜索减少行数时,索引才会加快搜索速度。如果您仍然要读取所有(或大部分)行,则表扫描会更快。
仅当磁盘可以实际处理其他I / O时,并行读取才会更有效。在旋转磁盘上,额外的搜索只会使情况变得更糟。
(SQLite尝试避免存储临时结果。结果行在遍历游标时(尽可能多地)动态计算。)