(在WAL模式下使用Delphi 2010 +最新的SQLite)

我在多线程客户端应用程序中使用DISQLite(SQLite的Delphi端口)(尚未发布,因此如果确实需要,我可以更改数据库引擎)

我的探查器清楚地说这是一个愚蠢的决定,我将其跟踪到2-3个在单线程应用中执行时非常简单的SQL语句,但这是因为线程锁定/等待(SQLite实际上在尝试多个线程时表现不佳)同时写)

我尽力优化了代码/避免了瓶颈,但是经过数周的辛苦工作,我现在想知道转储SQLite和选择其他数据库引擎是否不仅更容易(?)

我的要求是:

  • ACID
  • 很好的同时读/写(记录级别)支持
  • (非常)快速且稳定的数据库引擎
  • B-树
  • Delphi 2010支持

  • 我只使用带有索引的基本INSERT/UPDATE/DELETE命令,一点也不花哨。因此,我的SQL要求是相对基本的(不需要联接或其他“更高级”的SQL东西)。

    我也愿意接受NQL解决方案,只要它支持上述要求即可。

    我的研究成果是Berkley DB,如果我正确理解的话,它是具有并发写入支持的SQLite的修改版本,但是问题在于,对于delphi而言,它并不是真的。

    我也读过《京都内阁》,但是再说一次,没有德尔福支持:(

    任何建议都将受到欢迎,

    谢谢!

    最佳答案

    如果满足以下条件,您的申请速度是多少?

  • 您的所有线程仅使用一个DB连接。
  • 您可以通过全局关键节来保护数据库连接访问。

  • 然后,您可以尝试我们的Sqlite3 static binding,它是在没有线程互斥锁的情况下编译的:
    #define SQLITE_THREADSAFE 2
    //  assuming multi-thread safety is made by caller - in our framework, there is
    // only one thread using the database connection at the same time, but there could
    // be multiple database connection at the same time (previous was 0 could be unsafe)
    #define SQLITE_OMIT_SHARED_CACHE 1
    // no need of shared cache in a threadsafe calling model
    

    我们在mORMot ORM框架中使用了这样的模型,并与四个级别的缓存相关联:
  • 语句缓存,可重用SQL语句,并即时绑定(bind)参数;
  • 数据库级别的全局JSON结果缓存,在任何INSERT/UPDATE上全局刷新;
  • 在服务器端的指定表或记录的CRUD/RESTful级别调整记录缓存;
  • 在客户端的指定表或记录的CRUD/RESTful级别上调整了记录缓存。

  • 产生的性能一点也不差-即使在全局关键部分,它也可以在多线程访问中很好地扩展。当然,SQlite3的设计不像Oracle那样可扩展!但是我已经在很多客户的实际应用程序中使用了SQlite。您可以考虑使用FireBird,它具有用于客户端-服务器的更复杂(且经过调整)的体系结构。

    关于提高写作速度,您可以将您的写作分组为一个事务,这样会更快。 这就是我使用的for speed-up writing,您可以将这个概念扩展到多个客户端:在服务器端,您将写操作重新分组为共享事务,该事务将在超时时间(例如一秒钟)后提交。

    SQLite3进行此类添加的速度非常快(对于带有绑定(bind)参数的已准备好的INSERT语句,添加速度甚至更快),但对于单个添加而言,速度却很慢,因为它必须使用低级API锁定整个文件,这真是太慢了。为了使其成为ACID,请确保始终处理提交。实际上,其他DB引擎通过隐藏在后台的类似过程实现了良好的并发速度。为了确保可以从多个进程访问同一文件,SQLite3的默认写方法应该是这样的-但是在您的Client-Server应用程序中,您可以依靠这样的事实,即您将是唯一访问该文件的人。 SQLite3数据库文件,因此将是安全的。

    关于database - 并发编写的SQLite替代方法(Delphi),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9264772/

    10-10 22:20