一尘不染

使用SQLite3 + Node.js的最佳实践

node.js

我有一个普通的Node.js脚本,该脚本通过API从Wikipedia中提取数据并将其存储在SQLite数据库中。我正在使用此node-
sqlite3
模块。

在某些情况下,我要提取多达60万篇文章中的数据,并在数据库中连续存储有关每篇文章的一些元数据。从API中以500为一组检索文章。

检索带有500条文章中的数据的JSON对象的请求将对象传递给此回调:

//(db already instantiated as 'new sqlite.Database("wikipedia.sqlite");')

function callback(articles) {
    articles.forEach(function(article) {
        db.run("INSERT OR IGNORE INTO articles (name, id, created) VALUES (?,?,?)", [article["title"], article["pageid"], article["timestamp"]]);
    });
}

这些模块默认情况下并行运行,但是node-sqlite3的文档包括一个串行操作示例,如下所示:

db.serialize(function() {
  db.run("CREATE TABLE lorem (info TEXT)");

  var stmt = db.prepare("INSERT INTO lorem VALUES (?)");
  for (var i = 0; i < 10; i++) {
    stmt.run("Ipsum " + i);
  }
  stmt.finalize();
}

我试图模仿这一点,但几乎没有发现性能差异。我做错了吗?目前,从API检索数据的速度比写入数据库的速度要快得多,尽管它不会慢得令人无法忍受。但是用600K个单独的INSERT命令修改数据库感觉很笨拙。

更新 :每个接受的答案,这似乎适用于node-
sqlite3,而不是本机解决方案。(请参阅本期)。

    db.run("BEGIN TRANSACTION");
function callback(articles) {
        articles.forEach(function(article) {
            db.run("INSERT OR IGNORE INTO articles (name, id, created) VALUES (?,?,?)", [article["title"], article["pageid"], article["timestamp"]]);
        });
    }
    db.run("END");

阅读 1345

收藏
2020-07-07

共1个答案

一尘不染

在对SQLite数据库进行多次插入时,需要将插入的集合包装到事务中。否则,SQLite将等待每个插入的磁盘完全旋转,同时对插入的每个记录进行写后读取验证。

在7200 RPM时,磁盘盘再次旋转大约需要1/60秒,这是计算机时间的永恒。

2020-07-07