【发布时间】:2013-09-24 20:12:11
【问题描述】:
我有一个适度的 Node.js 脚本,它通过 API 从 Wikipedia 中提取数据并将其存储在 SQLite 数据库中。我正在使用这个node-sqlite3 模块。
在某些情况下,我会提取超过 600,000 篇文章的数据,并将关于每篇文章的一些元数据连续存储在数据库中。从 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,而不是原生解决方案。 (见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 表示“开始交易”的想法。您可以根据数据库大小来提高速度的其他方法是安装 ram 驱动器并从那里运行数据库。在 Windows 上,我过去使用过 OSFMunt,效果非常好。
-
抱歉,您能否解释一下更新部分,因为我不明白。你为什么要在调用 db.run 之间声明一个函数?有错吗?
标签: javascript node.js sqlite