LoginSignup
1
0

Node-Postgres で大量データを bulk insert した時の備忘録

Last updated at Posted at 2022-07-14

経緯

node-postgresを使用してbulk insertする時に苦労したので、備忘録を残す。

実行環境

  • linux
  • nodejs
  • postgres

性能比較

1行ずつのINSERTとの性能比較については、こちら(1000万件のINSERTを映画1本分ぐらい時間節約できた話)を参照。

postgres の準備

下記サイトを参考に node-js から postgres に接続する準備をする。
Node-Postgres を使ったときに、試行錯誤してできた Postgres クラス

大量データを 1000 行単位に分ける

paramsにはINSERT時のパラメータを配列で格納しておく。

[
  ['001', 'hoge'],
  ['002', 'fuga'],
  ['003', 'piyo'],
]

※追記
上限1000件は他のSQL言語でした。
postgresのbulk insertは一度に1000件が上限とのことなので、 処理したいデータを1000件ずつ詰め直す。

※もっといい方法があれば教えてください。

const makeBulkArray = (params) => {
  let bulkArray = [];
  let remaining = params;

  // 残り件数が1000より少なくなるまで
  while (remaining.length > 1000) {
    // postgresのバルクインサートは1000件が上限
    let oneBulk = remaining.slice(0, 1000);
    bulkArray.push(oneBulk);
    // 処理配列に詰めたデータを取り除く
    remaining = remaining.slice(1000);
  }
  // 残り件数が1000件より少ない場合の余りデータを最後に詰める
  if (remaining.length > 0) bulkArray.push(remaining);

  return bulkArray;
};

bulk insert する

参考にさせていただいたサイト(PostgreSQL に node-postgres モジュールを使って BULK INSERT をする方法)のとおりにやると、現在のpg-formatでは動かせないようで公式ドキュメントを見て調整した。

const format = require('pg-format');
const insertData = async (params) => {
  // poolからクライアント接続
  const pg = await getClient();
  // pg-formatを使って、pgが実行できるSQLを生成
  const sql = format('INSERT INTO test_table (id, name) VALUES %L', params);

  await pg.query(sql); // SQL実行
  await pg.release(); // クライアントをpoolに返す
};
insertData(bulkArray);
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0