Я пытаюсь выполнить запрос вставки для каждой строки потока запросов, используя pg-обещание с pg-query-stream. При таком подходе использование памяти увеличивается с каждым выполненным запросом.
Я также сузил проблему до выполнения любого запроса во время потока, а не только вставки. В настоящее время я слушаю события «данных» в потоке, приостанавливаю поток, выполняю запрос и возобновляю поток. Я также попытался передать поток запросов в поток для записи, который выполняет запрос, но я получаю сообщение об ошибке, что соединение БД уже закрыто.
let count = 0;
const startTime = new Date();
const qs = new QueryStream('SELECT 1 FROM GENERATE_SERIES(1, 1000000)');
db.stream(qs, stream => {
stream.on('data', async () => {
count++;
stream.pause();
await db.one('SELECT 1');
if (count % 10000 === 0) {
const duration = Math.round((new Date() - startTime) / 1000);
const mb = Math.round(process.memoryUsage().heapUsed/1024/1024);
console.log(`row ${count}, ${mb}MB, ${duration} seconds`);
}
stream.resume();
});
});
Я ожидал, что использование памяти будет колебаться вокруг постоянного значения, но вывод выглядит следующим образом:
row 10000, 105MB, 4 seconds
row 20000, 191MB, 6 seconds
row 30000, 278MB, 9 seconds
row 40000, 370MB, 10 seconds
row 50000, 458MB, 14 seconds
Чтобы достичь строки 60000, требуется более 10 минут.
UPDATE:
Я отредактировал приведенный выше код, добавив в него async / await, чтобы дождаться завершения внутреннего запроса, и увеличил ряд до 10 000 000. Я запустил процесс узла с 512 МБ памяти, и программа значительно замедляется при приближении к этому пределу, но не вылетает. Эта проблема возникла с v10, а не с v11 + узла.