0

私はTediousを使用RxJSして、SQL Server に対して SQL クエリを実行し、Observable. この関数は、次の動作を定義します。

export function msExecute(sql) {
  return new Observable(observer => {
    config.database.sams.requestTimeout = 60000;

    var connection = new mssql.Connection(config.database.sams, function (err) {
      var request = new mssql.Request(connection);
      request.stream = true;
      request.query(sql);
      request.on('row', row => {
        observer.next(row);
      });
      request.on('error', err => {
        observer.error(err);
      });
      request.on('done', () => {
        observer.complete();
        connection.close();
      });
    });
    connection.on('error', error => console.log(`mssql error == ${error}`));
  });
}

処理したい最大 11 万件のレコードを返す SQL クエリがありますが、実行中に次のエラーが発生します。

<--- Last few GCs --->

   27330 ms: Scavenge 1396.7 (1457.4) -> 1396.7 (1457.4) MB, 1.4 / 0 ms (+ 2.0 ms in 1 steps since last GC) [allocation failure] [incremental marking delaying mark-sweep].
   28635 ms: Mark-sweep 1396.7 (1457.4) -> 1396.6 (1457.4) MB, 1304.9 / 0 ms (+ 2.9 ms in 2 steps since start of marking, biggest step 2.0 ms) [last resort gc].
   29936 ms: Mark-sweep 1396.6 (1457.4) -> 1396.5 (1457.4) MB, 1300.3 / 0 ms [last resort gc].


<--- JS stacktrace --->

==== JS stack trace =========================================

Security context: 0x4035aee3ac1 <JS Object>
    1: /* anonymous */(aka /* anonymous */) [/home/njones/projects/test-forge/node_modules/orawrap/lib/connectionmanager.js:250] [pc=0x20cbecafa065] (this=0x4035ae04189 <undefined>,resolve=0x3896ea762871 <JS Function resolvePromise (SharedFunctionInfo 0x203f09a91f11)>,reject=0x3896ea762829 <JS Function rejectPromise (SharedFunctionInfo 0x203f09a91fb9)>)
    2: lib$es6$promise$$internal$$initiali...

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory

一度行ったすべての結果が必要なわけではないため、結果を個別のクエリにチャンクするソリューションが機能しますが、その方法がわかりません。

4

1 に答える 1

0

このような場合、Node.js ストリームを利用する必要があります。SQL クエリの結果をどう処理するかが明確でないため、より具体的なアドバイスを提供することは困難です。

基本的に、クエリ結果を独自のストリームにパイプする必要があります。

request.pipe(stream);

ストリームを使用すると、クエリ結果の出力が時々一時停止され、1 つの大きな結果によってシステム リソースを使い果たすことなく、結果を小さなチャンクで処理できるようになります。

または、ストリームから直接読み取ってみることができます。

request.read();

通常、ストリームは文字列とバッファのみを操作します。オブジェクト モードのストリームは、バッファーと文字列以外の汎用 JavaScript 値を発行できます。requestあなたがオブジェクトモードのストリームであると仮定するとread()、結果の1行が返されます。

ストリームは非常に重要ですが、Node.js のややこしい部分です。詳細については、ストリーム ハンドブックをご覧ください。

于 2016-01-19T19:14:10.623 に答える