【问题标题】:Why in memory mode donot accelerate in sqlite为什么在内存模式下不要在 sqlite 中加速
【发布时间】:2026-02-07 01:35:01
【问题描述】:

有一个查询全表,有500万条记录,耗时60s左右。如何优化这个? 我尝试使用sqlite的内存模式,理论上这应该更快,因为整个数据库都存储在memroy中。但是,它的成本几乎相同。 像这样的表架构:

CREATE TABLE tbl0(estimateid int, seq int,  field1 int NULL, field2 int NULL,  field3 int NULL,  field4 int NULL);
CREATE INDEX tbl0_idx on tbl0(estimateid);
CREATE TABLE tbl1(seq int, companyid int, field1 int NULL, field2 int NULL,  field3 int NULL,  field4 int NULL, field5 int NULL);
CREATE INDEX tbl1_idx on tbl1(seq);
CREATE TABLE tbl2(symbolid int, relatedcompanyid int,  value char(64),  field1 int NULL, field2 int NULL,  field3 int NULL,  field4 int NULL, field5 int NULL);
CREATE INDEX tbl2_idx on tbl2(relatedcompanyid);

这是查询,需要连接3个表的查询:

>explain query plan select tbl0.estimateid, tbl1.seq, tbl1.companyid, tbl2.value from tbl0, tbl1, tbl2 where tbl0.seq = tbl1.seq and tbl1.companyid = tbl2.relatedcompanyid;
0|0|1|SCAN TABLE tbl1
0|1|2|SEARCH TABLE tbl2 USING INDEX tbl2_idx (relatedcompanyid=?)
0|2|0|SEARCH TABLE tbl0 USING AUTOMATIC COVERING INDEX (seq=?)

如何加速这个查询?似乎不可避免地会完全扫描一张桌子。每张表包含大约 500 万条记录,这个查询需要很长时间(几分钟)。 当我将 db 放入内存时,使用这个 #sqlite3 :memory:,它对速度没有任何影响。 非常感谢帮助。

【问题讨论】:

  • 为了优化这一点,不要扫描 500 万条记录。

标签: sqlite optimization in-memory-database sql-execution-plan


【解决方案1】:

根据文档,全索引扫描(类型:索引)是您选择的全表扫描之后可能出现的第二差执行计划。 p>

全表扫描对数据库来说是一种资源密集型操作,除非你提高内存、CPU 速度、索引表、减少记录数等,否则幕后没有什么魔力。这就是为什么你没有当您将所有内容移至内存时,您注意到速度有任何急剧增加。

您应该尽量避免这种情况并进行更好的查询,或者优化数据库和表结构。请参考EXPLAIN QUERY PLANQuery Planning,以获取有关 SQL 执行以及如何优化它的更多详细信息。

很难说更多更具体,因为在您最初的问题中,您没有提供数据库结构、数据特征、查询等。

【讨论】:

  • 你能告诉我如何加速上面的连接查询吗?好像一张表会被全扫描,如何确定要扫描哪张表,如果可以的话,我可以减少tbl2的记录,并告诉sqlite扫描tbl2,搜索tbl1和tbl0。这样查询我觉得会更快。
  • @wushiqi,在你的情况下,我建议现在为你的表使用正确的索引——它会进行全表扫描,只是因为要找到值——它需要搜索整个数据.索引是数据库搜索引擎可以用来加速数据检索的特殊查找表。简而言之:用于表连接的列通常是完美的候选者,以及经常用作查找条件的列。
  • 我已经创建了如上图所示的索引。你能告诉我如何优化这个吗?现在每个表包含 500 万条记录,这个查询花费 300s,总共产生 300,000,000 条记录。我非常渴望优化。非常感谢!!!
【解决方案2】:

您的数据库不在内存中;你做错了什么。我构建了一个程序,将 500 万条记录加载到另一个内存数据库系统中,完整的顺序扫描只用了不到 800 毫秒。即使 SQLite 的速度只有我使用的内存数据库系统的一半,它也应该只需要一两秒。

另一种可能性是您在获取每一行后写入控制台,或执行一些其他逻辑,这会导致整体缓慢。

【讨论】:

    最近更新 更多