Рекомендации по использованию SQLite3 + Node.js

У меня есть скромный Node.js script, который извлекает данные из Википедии через API и сохраняет их в базе данных SQLite. Я использую этот node-sqlite3 модуль.

В некоторых случаях я собираю данные по 600 000 статей и храня некоторые метаданные о каждом из них в строке в db. Статьи извлекаются группами по 500 из API.

Запрос, который извлекает объект JSON с данными в 500 статьях, передает объект этому обратному вызову:

//(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 намного быстрее, чем записываются в БД, хотя это не невыносимо медленно. Но избиение БД с помощью индивидуальных команд INSERT с числами 600K кажется неуклюжим.

UPDATE: В соответствии с принятым ответом это работает для node -sqlite3, вместо собственного решения. (См. Issue).

    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");

Ответы

Ответ 1

Когда вы делаете несколько вставок в базу данных SQLite, вам необходимо обернуть коллекцию вставок в транзакцию. В противном случае SQLite будет ожидать, что дисковые планшеты будут полностью вращаться для каждой вставки, в то время как он выполняет проверку чтения после записи для каждой записи, которую вы вставляете.

При скорости вращения 7200 об/мин требуется около 1/60 секунды для дискового диска снова, что является вечностью в компьютерном времени.