6

我正在分配有 4 个处理器的 Ubuntu 虚拟机上开发一个多线程 sqlite 数据库应用程序。我正在使用 sqlite 版本 3.7.13。我创建了一个测试来验证多个线程/连接可以同时从数据库中读取。

我有两个可执行文件。第一个可执行文件只是创建一个数据库,在该数据库中创建一个表,将 50 个项目插入该表,然后关闭该数据库。这根本不涉及任何多线程,只是为了提供一个包含条目的数据库。

第二个可执行文件创建多个线程以从数据库中读取并等待它们完成并记录所有线程完成所花费的时间。每个线程执行以下操作: - 使用 sqlite_open_v2() 创建一个数据库连接,以便每个线程都有自己的到从第一个可执行文件创建的数据库的单独连接 - 在一个数据库表上执行 100000 SELECTS(每个选择查询table) - 关闭数据库连接

当我在每个线程中将 SQLITE_OPEN_READWRITE 指定为 sqlite_open_v2 的标志运行此测试时,我得到以下执行所有查询的总时间结果:

1 线程 - 0.65 秒 2 线程 - 0.70 秒 3 线程 - 0.76 秒 4 线程 - 0.91 秒 5 线程 - 1.10 秒 6 线程 - 1.28 秒 7 线程 - 1.57 秒 8 线程 - 1.78 秒

这些结果与我预期的一样,因为当我添加线程时,时间稍微增加了一点(可能是由于线程之间的上下文切换和其他原因),这意味着读取基本上是并行完成的。

但是,当我使用 SQLITE_OPEN_READWRITE | 运行相同的测试时 标志的 SQLITE_OPEN_SHAREDCACHE,我得到以下结果:

1 线程 - 0.67 秒 2 线程 - 2.43 秒 3 线程 - 4.81 秒 4 线程 - 6.60 秒 5 线程 - 8.03 秒 6 线程 - 9.41 秒 7 线程 - 11.17 秒 8 线程 - 12.79 秒

从这些结果看来,共享缓存模式中的某些东西正在阻止数据库中同时发生多个读取。我已经验证了线程并行运行确实不同(线程 4 读取、线程 8 读取、线程 2 读取等,而不是线程 1 执行所有读取,线程 2 执行所有读取,线程 3 执行所有读取, ETC。)。但是,似乎每个单独事务的读取都是以串行方式完成的,或者其他事情正在减慢共享缓存中的数据库。

为什么当我在共享缓存模式下添加线程而不是没有它时,我会看到如此高的时间增加?有没有办法解决这个问题并仍然使用共享缓存模式?

谢谢你的帮助。非常感谢。

4

1 回答 1

1

目前,我只能说在shared cache mode每个线程中read mutex lock()对每个请求进行多次附加(锁定共享缓存、锁定主表、锁定请求表)。当然,它有一些开销。

为了避免这种情况,您可以使用PRAGMA read_uncommitted = true;,但是如果另一个数据库连接在读取表时修改了表,这可能会导致查询结果不一致,但这也意味着读取未提交模式下的连接打开的读取事务既不能阻塞也不能被任何其他连接阻止。

(你能提供你的代码吗?)

于 2014-08-15T14:27:50.207 回答