4

我一直在研究提高我网站的 SQLite 性能,尤其是在事务方面。本质上,我正在寻找一种在进程中延迟数据库写入的方法,以便它们可以一次完成。但是,当我累积更新查询时,我希望其他进程能够读取和写入数据库,并且只有在进程中发出提交时才锁定文件以进行写入。

在查看文档时,似乎一旦在事务中发出更新命令,进程就会获得一个保留锁,这(如果我没记错的话)意味着任何其他尝试将更新查询添加到自己的事务的进程或者提交事务是无法这样做的,因此会阻塞,直到事务提交到带有锁的进程上。

我确信针对此特定功能有很好的数据完整性原因。我只能说,在我的情况下,同时执行这些更新没有危险。

一种解决方案是,在每个过程中,我可以在数组中累积我希望调用的查询文本,然后在我准备好编写时循环它,但我想知道是否有可能进行 SQLite 事务自动为我执行此操作。

更新:当我说“一次完成所有更新”时,我的意思是在 SQLite 中使用事务来仅获得一个独占锁并在每个进程中写入一次磁盘,而不是每个查询一次。这导致使用 SQLite 的速度提高 100 倍。

我已经进行了一些基本测试,似乎一旦您有多个进程向其事务添加查询,一旦您点击更新查询,该进程就会尝试获取 RESERVED 锁。由于只有一个进程可以拥有保留锁,这意味着任何其他尝试获取锁的进程都将阻塞,直到拥有锁的进程完成事务。

我承认这个问题可能是一个过早的优化,因为我还没有遇到任何性能损失,但是我已经运行了一些简单的测试,并且 100 个用户在我的机器上创建和运行一个包含 100 个查询的事务大约需要 4 秒。

4

2 回答 2

3

SQLite 支持ATTACH 将一个数据库附加到另一个数据库。也许您可以将数据累积在一个单独的数据库中,当您准备好合并累积的行时,附加单独的数据库,在单个语句中复制行,然后分离。

编辑:在 sqlite-users 的邮件列表线程中提出了与 OP 类似的建议,并进行了一些后续讨论。

于 2008-11-15T01:43:20.253 回答
1

比附加数据库更好的是只创建一个临时表。(创建临时...)

并看看新的 WAL 日志模式,它完全可以手动执行您尝试执行的操作,并且它允许同时写入和读取(虽然不是同时写入)。

#pragma journal_mode=WAL

于 2010-12-21T10:16:55.110 回答