Better-sqlite3 性能

来自泡泡学习笔记
跳到导航 跳到搜索

在SQLite3数据库中,在某些情况下同时进行读写操作可能会非常慢。由于并发性在Web应用程序中通常非常重要,建议启用WAL模式以大大提高整体性能。


db.pragma('journal_mode = WAL');


WAL模式有一些需要考虑的缺点:

  • 涉及附加数据库的事务对于每个单独的数据库是原子的,但对于所有数据库作为一个集合来说不是原子的。
  • 在极少数情况下,WAL文件可能会遇到“检查点饥饿”(见下文)。
  • 有些硬件/系统限制可能会影响一些用户,在这里列出


然而,在大多数Web应用程序中,你用这些缺点换取了极快的性能。


检查点饥饿

检查点饥饿是指SQLite3由于持续对数据库进行并发读取而无法回收WAL文件。如果发生这种情况,WAL文件将无限制地增长,导致不可接受的磁盘使用量和性能下降。


如果你不同时从多个进程或线程访问数据库,你永远不会遇到这个问题。


如果你确实同时从多个进程或线程访问数据库,只需在WAL文件变得过大时使用wal_checkpoint(RESTART)语句。

setInterval(fs.stat.bind(null, 'foobar.db-wal', (err, stat) => {
  if (err) {
    if (err.code !== 'ENOENT') throw err;
  } else if (stat.size > someUnacceptableSize) {
    db.pragma('wal_checkpoint(RESTART)');
  }
}), 5000).unref();


关于持久性的说明

这个SQLite3分发版使用了SQLITE_DEFAULT_WAL_SYNCHRONOUS=1 编译时选项,这使得处于WAL模式的数据库默认为“NORMAL”同步设置。这允许应用程序实现极高的性能,但在WAL模式下引入了轻微的持久性损失。


你可以通过运行db.pragma('synchronous = FULL')来覆盖此设置。