【问题标题】:SQLite C++ API Transactions slowSQLite C++ API 事务缓慢
【发布时间】:2017-09-23 19:20:05
【问题描述】:

我对 SQLite 有疑问。似乎每次调用都需要大约 300 毫秒才能执行。经过一些测试,我注意到延迟是由事务引起的。 8 次带有隐式事务的普通插入大约需要 2 秒,但是,如果我在插入之前启动事务并在之后提交,我可以同时进行近一百万次插入。受影响的调用包括 DROP TABLE、CREATE TABLE、INSERT,我假设还有其他调用(可能所有隐式开始事务的调用)。

更多信息:

  • 从 SQLite 网站 (3200100) 下载源合并
  • 使用 Visual Studio 将其编译为静态库(未使用任何编译器标志,尽管我一直在玩弄它们但没有运气)
  • 我使用 sqlite3_open16,然后是 sqlite3_prepare16_v3,然后是 sqlite3_step 开始执行和/或接收第一个结果
  • 没有多线程,没有多进程访问,数据库文件被这个程序独占打开
  • 如果我在我的 SSD (960 EVO) 上创建文件,则“事务延迟”会从 300 毫秒降至 10 毫秒。虽然仍然是一个荒谬的高价值,但我觉得我的磁盘速度不应该影响任何减慢交易速度的因素?
  • 阻塞的函数是 sqlite3_step(例如,我必须调用具有该名称的函数来执行 DROP TABLE,这也让我很恼火,但这并不重要)
  • 编辑:在事务期间,CPU 使用率为 100%。

顺便说一句,如果您知道表的每一行都是 64 字节,是否可以“帮助”SQLite 组织数据?

我希望您能帮助我解决这个问题,或者可能推荐一个替代方案(关系型、c++ api、基于文件、高性能) 非常感谢!

【问题讨论】:

  • DROP 和 CREATE TABLE 可能非常昂贵,因为除非创建新数据库或对现有数据库模式进行复杂升级,否则执行这两个命令是不常见的。 DROP/CREATE 还必须对数据库元数据(模式)进行大量更改/检查。除非表上有很多索引/外键,否则 INSERT 应该很快。
  • 这是FAQ。考虑使用异步写入的WAL mode

标签: c++ database performance sqlite transactions


【解决方案1】:

SQLite 做了很多努力来确保它不会遭受数据损坏,因此对于隐式事务,您会受到硬盘速度的限制。

通过事务,将数据写入其他位置,并且只提交一次磁盘,并且速度更快

来自sqlite speed

打开同步后,SQLite 在关键点执行 fsync() 系统调用(或等效的),以确保关键数据已实际写入磁盘驱动器表面。

创建事务时,数据写入其他文件,只有当所有数据都提交后,才会支付fsync成本,并且全部一起。这是该部分配置的价格。积极的一面是,我从未因损坏而遭受过 sqlite 数据丢失的困扰。

我觉得我的磁盘速度不应该影响任何减慢交易速度的因素?

这是一个重要的权衡。如果您想提高数据完整性,那么您的磁盘速度是相关的。

提交事务需要多长时间?

来自sqlite faq :19 why are transactions slow

SQLite 在普通台式计算机上每秒可以轻松执行 50,000 或更多的 INSERT 语句。但它每秒只会进行几十次交易。

你可以:-

  1. 使用事务绑定更多工作。费用是每笔交易的费用,因此可以增加。
  2. 使用临时表。临时表不会影响性能,并且会全速运行。
  3. 不推荐。使用PRAGMA synchronous=OFF 禁用同步写入。

【讨论】:

  • 将日志模式设置为 WAL 确实是我想要的(从一致性的角度和性能的角度来看)。现在,在普通硬盘上每秒处理 32 个事务和在 SSD 上超过 512 个事务时,这些值现在更有意义。非常感谢,我不敢相信我错过了常见问题解答中的信息!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多