0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

バルクでinsertして採番された主キーを取得する方法

Last updated at Posted at 2024-02-11

バルクでインサートは早いけど・・

  • バルクは採番されたキー達を取得することができない。
  • 一個一個for文でinsertすれば、例えばPHPなら$model->insert_id;とかで取れる。
  • でもバルクだと取れない。性能改善したいのにこれだと後続処理を大幅に変える必要があるか、主キー項目でない項目でinsertしたデータをselectし直さなきゃいけない。きっとそれは遅い・・・

ならキーを自分で採番すればいいじゃん

  • こんな感じで解決。実装はポスグレで行った。
    ※ 言語は問わないと思ったので適当言語・・
  1. シーケンスになってる主キーの現在値を取得
    $maxId = select nextval('主キー');
    
  2. バルクで入れたい項目の数だけキー値をインクリメント
    $minId = $maxId;  // 後で使うので取っとく
    $maxId += count($bulkInsertList);
    
  3. インクリメントした数だけシーケンスを進めちゃう
    select setval('主キー', $maxId);
    
  4. バルクで入れたい配列に主キー値を設定した上でバルクインサートする
    for($bulkInsertList) {
      // (略)
      // $minId ~ $maxIdを主キー項目に設定
    }
    
    // 主キー項目入りのバルクで入れたい配列をバルクインサート
    bulkInsert($bulkInsertList);
    
  5. 後続処理で主キー項目を使って処理継続できる。

ポイント&注意

  • setval()などでシーケンスを予め進めておけばこの処理に時間がかかってる間に別の処理で当該テーブルにインサートされても進めた先のシーケンスから採番されるから主キーはズレない。
  • シーケンス進めるのはトランザクション張っててもロールバックできないから、処理ミスってるとめっちゃシーケンス進んじゃう可能性あるので注意。
0
1
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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?