我想从 Sqlite 数据库中获取并导出大量(5 - 12 百万行)存档数据到 csv 文件。这样做时,整个服务器都被阻止了。服务器无法处理其他连接(例如,我无法在浏览器的另一个选项卡中打开网站)。
Node.JS 服务器部分:
function exportArchiveData(response, query){
response.setHeader('Content-type', 'text/csv');
response.setHeader('Content-disposition', 'attachment; filename=archive.csv');
db.fetchAllArchiveData(
query.ID,
function(error, data){
if(!error)
response.write(data.A + ';' + data.B + ';' + data.C + '\n');
},
function(error, retrievedRows){
response.end();
});
};
Sqlite 数据库模块:
module.exports.SS.prototype.fetchAllArchiveData = function (
a, callback, complete) {
var self = this;
// self.sensorSqliteDb.all(
self.sensorSqliteDb.each(
'SELECT A, B, C '+
'FROM AD WHERE '+
' A="' + a + '"'+
' ORDER BY C ASC' +
';'
,
callback,
complete
);
};
我还在 AD 上创建索引,如 CREATE INDEX IAD ON AD(A, C) 和 EXPLAIN QUERY PLAN 显示该索引由 sqlite 引擎使用。
尽管如此,当我调用 exportArchiveData 服务器正确发送数据但在此期间无法执行其他操作时。我有大量数据(要发送 5 到 12 百万行),所以大约需要 3 分钟。
我怎样才能防止它阻塞整个服务器?
我认为如果我使用 EACH 并且会有回调,服务器会响应更快。内存使用量也很大(大约 3GB 甚至更多)。我能以某种方式阻止这种情况吗?
在回答评论时,我想补充一些说明:
我使用developmentseed 的 node-sqlite3。它应该是异步和非阻塞的。它是。准备好声明后,我可以请求主页。但是当服务器开始提供数据时,Node.js 服务器被阻塞。我猜那是因为对主页的请求是一个调用某个回调的请求,而有数百万个请求回调处理存档数据“EACH”。
如果我从 linux 命令行使用 sqlite3 工具,我不会立即获得行,但只要 node-sqlite3 是非阻塞的,这不是问题。
是的。我正在达到 CPU 最大值。更糟糕的是,当我请求两倍的数据时,会使用整个内存,然后服务器永远冻结。