试图破解SQLite3并发写作的方法,还有更好的方法吗?

The*_*ude 6 delphi sqlite acid delphi-xe2

我使用Delphi XE2DISQLite v3(它基本上是SQLite3的一个端口).我喜欢所有的sqlite3的,除了缺乏并发写的,特别是我广泛地依赖于多线程在这个项目:(

我的探查器明确表示我需要对此做些什么,所以我决定使用这种方法:

  1. 每当我需要在DB中插入一条记录,而不是做一个INSERT,我write在一个特殊的foler中的SQL查询,即.

    WriteToFile_Inline(SPECIAL_FOLDER_PATH + '\' + GUID, FileName + '|' + IntToStr(ID) + '|' + Hash + '|' + FloatToStr(ModifDate) + '|' + ...);

  2. 我添加了一个timer(在主应用程序线程中)每分钟触发,解析这些文件,然后使用事务INSERT查询.

  3. 最后删除那些临时文件.

结果是我有500%的性能提升.此外,这种技术是ACID,因为我总是可以SPECIAL_FOLDER_PATH在电源故障后扫描并执行我发现的INSERT.

尽管结果很好,但我对使用的方法不太满意(至少可以说是hackish),我一直在想,如果我有一个类似于泛型的快速查找访问,线程安全,ACID列表,这将是更清洁(可能更快?)

所以我的问题是:你对Delphi XE2有什么了解吗?


PS.我相信你们很多人在阅读上面的代码时会感到震惊并且会在这一点上开始侮辱我!请成为我的客人,但如果您了解更好(即更快)的ACID方法,请分享您的想法!

Arn*_*hez 5

您将插入发送到队列(将重新排列插入,并通过预准备语句连接它们)的想法非常好.在主线程或分离的线程中使用计时器取决于您.它将避免任何锁定.

不要忘记使用事务,然后例如每100/1000次插入一次.

关于使用SQLite3的高性能,请参阅此博客文章(以及下图):

速度比较

在此图中,最佳性能(文件关闭)来自:

  • PRAGMA synchronous = OFF
  • 使用预备语句
  • 在交易中
  • 在WAL模式下(特别是在并发模式下)

您也可以更改页面大小或日志大小,但上面的设置是最好的.请参阅https://stackoverflow.com/search?q=sqlite3+performance

如果您不想使用后台线程,请确保WAL为ON,准备语句,使用批处理,并重新组合您的进程以尽快释放SQLite3锁.

最好的性能将通过添加客户端 - 服务器层来实现,就像我们为mORMot所做的那样.