【问题标题】:Sqlite3: Drop indexes to improve Insert performance, but then Commits are slowSqlite3:删除索引以提高插入性能,但提交速度很慢
【发布时间】:2023-03-12 16:22:02
【问题描述】:

我有一个 Python 程序,它处理大量数据文件并从中提取记录,然后将它们插入 SQLITE3 数据库。 我按日期对数据库进行分区(每天创建一个新数据库)以减小大小,但它们仍然达到 9GB,并且插入速度逐渐变慢,因为表有索引。

所以在添加一堆记录之前我想删除索引,然后再添加它,记录应该插入得更快。但是我发现插入操作速度有所提高,但是每个记录批处理后的提交却需要永远!

这是一个来自日志的示例,带有索引:

DB-ADDREC-START|Adding 11425 records from 2017-05-01 into database...
DB-ADDREC-END| (Duration: 9.15 seconds)
DB-COMMIT-START|Committing database transaction..
DB-COMMIT-END| (Duration: 0.96 seconds)

删除索引后,提交时间变化很大,但变得非常大:

DB-ADDREC-START|Adding 10681 records from 2017-05-01 into database...
DB-ADDREC-END| (Duration: 0.06 seconds)
DB-COMMIT-START|Committing database transaction..
DB-COMMIT-END| (Duration: 2.29 seconds)

DB-ADDREC-START|Adding 11185 records from 2017-05-01 into database...
DB-ADDREC-END| (Duration: 0.20 seconds)
DB-COMMIT-START|Committing database transaction..
DB-COMMIT-END| (Duration: 21.28 seconds)

为了帮助我还设置了:

PRAGMA synchronous=OFF

另外我目前正在使用 WAL 日志模式

为什么提交时间变长了,我该如何防止呢?

【问题讨论】:

  • 在您的类比中,您忘记了拆卸自行车的目的。更准确的说法是花时间将自行车变成比步行快一个数量级的有效爬楼梯机上楼梯,然后又变回来。对于足够大的批处理作业,删除然后重新添加索引应该可以提高插入性能。无论哪种方式,这都不能解释为什么没有索引的提交时间会更长,我怀疑这与 WAL 或 NFS 上的数据库文件有关
  • 写 SQL 查询时我不骑自行车,因为这很危险。

标签: sql indexing sqlite insert commit


【解决方案1】:

在WAL模式下,数据库需要经过一定的改动后做checkpoints。 (这与您是否有索引无关,但有了索引,会更改更多数据,因此您应该会看到更频繁的检查点。)

做大改动时,disable WAL mode;这可能比禁用索引有更大的影响。

【讨论】:

  • 好的,我将尝试将日志模式设置回默认值(删除)。但是,我的 OP 中的两种情况都使用 WAL 模式,我仍然不明白为什么没有索引的提交时间要长得多。顺便说一句,数据库文件位于 NFS 上
  • 如果您使用 NFS,请阅读 sqlite.org/howtocorrupt.html,并考虑使用 OFF 日志模式(最快)。
猜你喜欢
  • 2011-11-08
  • 1970-01-01
  • 2020-05-05
  • 2016-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多