3

我正在开发一个用 C 编写的项目,该项目会生成近 350k 序列以保存在 sqlite 数据库中。对于每个序列,我必须在表中插入(或忽略)一个字符串并更新其他表中的一行。

我尝试了这个“指南”,但每秒无法达到超过 30k 的操作。

我正在使用每个 1M 操作的事务(插入和更新)和 PRAGMA 同步 = OFF

我有什么选择来解决这个瓶颈?

4

2 回答 2

4

实际上,SQLite 在普通台式计算机上每秒可以轻松执行 50,000 或更多的 INSERT 语句。但它每秒只会进行几十次交易。交易速度受磁盘驱动器转速的限制。一个事务通常需要磁盘盘片完全旋转两次,这在 7200RPM 磁盘驱动器上将您限制为每秒大约 60 个事务。

事务速度受到磁盘驱动器速度的限制,因为(默认情况下)SQLite 实际上会等到数据真正安全地存储在磁盘表面上之后才会完成事务。这样,如果您突然断电或操作系统崩溃,您的数据仍然是安全的。有关详细信息,请阅读 SQLite 中的原子提交。

默认情况下,每个 INSERT 语句都是它自己的事务。但是,如果您使用 BEGIN...COMMIT 包围多个 INSERT 语句,则所有插入都将分组到一个事务中。提交事务所需的时间在所有封闭的插入语句中分摊,因此每个插入语句的时间大大减少。

另一种选择是运行 PRAGMA synchronous=OFF。此命令将导致 SQLite 不等待数据到达磁盘表面,这将使写入操作看起来要快得多。但是,如果您在事务处理过程中断电,您的数据库文件可能会损坏。

请查看此常见问题解答,它解释了插入瓶颈问题等。

于 2013-05-22T00:15:18.687 回答
1

我通过简化查询提高了数据库的性能。

最初,我对应该添加到表中的每个元素都有一个 INSERT + UPDATE。通过简化,我创建了另一个表,一个临时表,对列没有任何约束,只需在其上插入数据。最后我使用:

CREATE TABLE my_table AS SELECT ... FROM my_tmp_table ... GROUP BY something

并使用我需要的所有约束创建我的最终表。

现在它达到了我需要的性能。

于 2013-05-30T21:56:46.777 回答