バルクでインサートは早いけど・・
- バルクは採番されたキー達を取得することができない。
- 一個一個for文でinsertすれば、例えばPHPなら
$model->insert_id;
とかで取れる。 - でもバルクだと取れない。性能改善したいのにこれだと後続処理を大幅に変える必要があるか、主キー項目でない項目でinsertしたデータをselectし直さなきゃいけない。きっとそれは遅い・・・
ならキーを自分で採番すればいいじゃん
- こんな感じで解決。実装はポスグレで行った。
※ 言語は問わないと思ったので適当言語・・
- シーケンスになってる主キーの現在値を取得
$maxId = select nextval('主キー');
- バルクで入れたい項目の数だけキー値をインクリメント
$minId = $maxId; // 後で使うので取っとく $maxId += count($bulkInsertList);
- インクリメントした数だけシーケンスを進めちゃう
select setval('主キー', $maxId);
- バルクで入れたい配列に主キー値を設定した上でバルクインサートする
for($bulkInsertList) { // (略) // $minId ~ $maxIdを主キー項目に設定 } // 主キー項目入りのバルクで入れたい配列をバルクインサート bulkInsert($bulkInsertList);
- 後続処理で主キー項目を使って処理継続できる。
ポイント&注意
- setval()などでシーケンスを予め進めておけばこの処理に時間がかかってる間に別の処理で当該テーブルにインサートされても進めた先のシーケンスから採番されるから主キーはズレない。
- シーケンス進めるのはトランザクション張っててもロールバックできないから、処理ミスってるとめっちゃシーケンス進んじゃう可能性あるので注意。