内存中的 SQLite 数据库可以并发扩展吗?

Posted

技术标签:

【中文标题】内存中的 SQLite 数据库可以并发扩展吗?【英文标题】:Can in-memory SQLite databases scale with concurrency? 【发布时间】:2011-02-03 17:53:38 【问题描述】:

为了防止 SQLite 内存数据库被清理,必须使用相同的连接来访问数据库。但是,使用相同的连接会导致 SQLite 同步对数据库的访问。因此,如果我有许多线程对内存数据库执行读取操作,那么在多核机器上运行的速度要比针对文件支持的数据库运行完全相同的代码要慢。

有什么方法可以两全其美?也就是说,允许对数据库进行多次并发调用的内存数据库?

【问题讨论】:

【参考方案1】:

答案是否定的。我询问了 SQLite 用户组,得到了 Pavel Ivanov 的以下回复:

不,SQLite 不支持对任何数据库的完全并发访问。这 您唯一可以获得的并发性是没有磁盘数据库 共享缓存(因此实际上在 记忆)。当然我不考虑并发选项 不同的过程。

【讨论】:

【参考方案2】:

如果您将页面大小和缓存大小设置为足够大以包含整个数据库,则将从缓存中完成读取操作,并且性能将几乎等于内存数据库。

【讨论】:

【参考方案3】:

从这里我明白答案是肯定的http://www.sqlite.org/faq.html#q6

【讨论】:

这只是意味着它可以安全地从多个线程中使用。我可以证明这一点。但它不能扩展——它只使用我的双核中的一个核。所以是以牺牲性能为代价的安全。更新我的标题以澄清。 “它只使用一个核心”——这意味着你的线程是这样调度的!这可能是由 sqlite 中的内部锁定或其他同步引起的。如果你真的想要 DB+并发,你应该考虑一些自定义代码,最终刷新到共享数据库。我认为你对 sqlite 的要求太多了。 关键是它适用于基于文件的 SQLite 数据库(100% CPU 消耗),但不适用于内存数据库。如果 SQLite 不支持这种情况,那很好,但我需要引用。 好吧。 100% 的 CPU 消耗看起来很奇怪,因为写入 HDD 一次只能由一个线程完成(HDD 中只有一个磁头)。那么可能是您的测试不正确?

以上是关于内存中的 SQLite 数据库可以并发扩展吗?的主要内容,如果未能解决你的问题,请参考以下文章

IOS中的Sqlite3并发问题

Android:扩展用户的通讯录。性能 ContentProvider vs Sqlite vs 内存中的列表

如何在特定地址创建 SQLite 内存数据库

sqlite3 从内存流中加载数据库文件

SQLite剖析之锁和并发控制

memcached写数据时存在并发问题吗