からのストリーム/パイプを使用して、私はこれが私のコードである10,000,000行は、すべてのクエリがメモリに `ノード-sqliteの各機能の負荷である、またはそれはハードディスク
を扱いたいですそれは:私のすべてのRAMを食べるか、または行の後にハードドライブの行から読み取りますか?
からのストリーム/パイプを使用して、私はこれが私のコードである10,000,000行は、すべてのクエリがメモリに `ノード-sqliteの各機能の負荷である、またはそれはハードディスク
を扱いたいですそれは:私のすべてのRAMを食べるか、または行の後にハードドライブの行から読み取りますか?
両方。 statement.each
は、機能が高速かつ同期の場合は余分なメモリを使用しませんが、非同期機能ではディスクからデータをロードできるだけ高速にすべての非同期処理を開始します。
https://github.com/mapbox/node-sqlite3/issues/686の投稿にも記載されているように、Statement.get()
を使用して目的の動作を得ることができます。パラメータなしのStatement.get()
は次の行をフェッチします。だから、このように、独自の非同期バージョンを実装することができます
function asyncEach(db, sql, parameters, eachCb, doneCb) {
let stmt;
let cleanupAndDone = err => {
stmt.finalize(doneCb.bind(null, err));
};
stmt = db.prepare(sql, parameters, err => {
if (err) {
return cleanupAndDone(err);
}
let next = err => {
if (err) {
return cleanupAndDone(err);
}
return stmt.get(recursiveGet);
};
// Setup recursion
let recursiveGet = (err, row) => {
if (err) {
return cleanupAndDone(err);
}
if (!row) {
return cleanupAndDone(null);
}
// Call the each callback which must invoke the next callback
return eachCb(row, next);
}
// Start recursion
stmt.get(recursiveGet);
});
}
注意、わずかに異なるStatement.each
に建設され、エラーが最後のコールバックに送られ、より構文とオプションのパラメータのサポートはありませんが。
もget
複数を発行することによって向上させることができ、これは通常Statement.each
関数よりも低速であることに注意next
が呼び出されたときに、次の行が待機している呼び出し、そのコードに従うことがはるかに困難です。スニペットを使用するため
例:
let rowCount = 0;
asyncEach(db, 'SELECT * from testtable', [], (row, next) => {
assert.isObject(row);
rowCount++;
return next();
}, err => {
if (err) {
return done(err);
}
assert.equal(rowCount, TEST_ROW_COUNT);
done();
});