我有一个普通的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命令修改数据库感觉很笨拙。
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");
在对SQLite数据库进行多次插入时,需要将插入的集合包装到事务中。否则,SQLite将等待每个插入的磁盘完全旋转,同时对插入的每个记录进行写后读取验证。
在7200 RPM时,磁盘盘再次旋转大约需要1/60秒,这是计算机时间的永恒。