Db.each de Node-SQLite que usa gran cantidad de memory para consultas amplias

Estoy intentando ejecutar la function enumerada a continuación en el nodo en una máquina virtual con 3,5 GB de memory. La consulta que estoy ejecutando devuelve aproximadamente 2.25 millones de filas. No funciona debido a lo que parece ser una pérdida de memory: si alguien ha encontrado esto o tiene sugerencias sobre cómo manejar el creciente problema de memory en esta llamada, se lo agradecería.

var sqlite3 = require('sqlite3').verbose(); db.each(query, function (error, data) { if (error) { console.log('Failed.'); } else { console.log('Current perf: ', process.memoryUsage()); } error = null; data = null; }, function (error, responseLength) { console.log('done with all'); }); 

Cada fila se ve así:

 2015-11-13T01:17:32Z|510|40.632087|-73.946855|315.47|2|20151112|9910715-SCPD5-SC_D5-Weekday-10-SDon|0|307840|73.51|5.53 

El objective es manejar cada fila de a una por vez y escribirlas en un CSV, línea por línea, a través de una transmisión. La idea era que, al hacer esto, evitaría tener que mantener toda la respuesta de la consulta en la memory, pero este objective parece frustrarse dada la situación actual.

Creo que necesitas usar una statement preparada y setImmediate (), como esta:

 var sqlite3 = require('sqlite3').verbose(); var stmt = db.prepare(query); doQuery(); function doQuery(){ stmt.get(function(error, data){ if(data){ if(error){ console.log(error); } else { // do something with data here. } setImmediate(function(){ doQuery(); }); } }); } 

Explicación:

1) Las declaraciones preparadas hacen que el cliente recupere cada fila por separado, en lugar de intentar get todos los resultados a la vez. El parámetro de datos no estará definido cuando llegue a la última fila.

2) setImmediate () se asegura de que el ciclo de callback no se llame recursivamente, lo que podría hacer explotar su stack de llamadas si el número de filas es demasiado alto.