我正在Ubuntu虚拟机上开发一个多线程sqlite数据库应用程序,该虚拟机分配了4个处理器。我使用的是sqlite版本3.7.13。我创建了一个测试来验证多个线程/连接可以同时从数据库中读取。
我有两个可执行文件。第一个可执行文件只创建一个数据库,在该数据库中创建1个表,在该表中插入50个项,然后关闭数据库。这根本不涉及任何多线程,只是为了提供一个包含条目的数据库。
第二个可执行文件创建多个线程以从数据库中读取并等待它们完成并记录所有线程完成所花费的时间。每个线程执行以下操作: 使用sqlite_open_v2()创建数据库连接,以便每个线程都有自己的连接到从第一个可执行文件创建的数据库 -perform在一个数据库表上执行100000 SELECTS(每个选择查询表中的一行) - 关闭数据库连接
当我在每个线程中将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执行其所有读取,等等。)。但是,似乎每个单独事务的读取都是串行完成的,或者其他东西正在减慢共享缓存中的数据库。
为什么我在共享缓存模式下添加线程时看到如此高的增长,而不是没有呢?有没有办法解决这个问题,仍然使用共享缓存模式?
感谢您的帮助。非常感谢。
答案 0 :(得分:1)
目前,我只能说shared cache mode
每个线程在每个请求上多次执行read mutex lock()
次锁定(锁定共享缓存,锁定主表,锁定请求表)。当然,它有一些开销。
要避免这种情况,您可以使用PRAGMA read_uncommitted = true;
,但如果另一个数据库连接在读取时修改了某个表,则会导致查询结果不一致,但这也意味着连接打开了一个读取事务read-uncommitted模式既不会阻塞也不会被任何其他连接阻塞。
(你可以提供你的代码吗?)