はじめに
本記事では、以下のようなケースに対応するための安全で実践的なデータ投入手順を紹介します。
目的:REF/SABカラムの組み合わせが全件異なる40万件のデータをINSERT
背景:DBAから「実行計画の取得のために本番想定データを入れてほしい」と依頼
ゴール:後から削除可能、安全に実行、実行ログも残す
前提条件
| 項目 | 内容 |
|---|---|
| DB | Oracle |
| 実行環境 | SQL*Plus または SQL Developer |
| 対象テーブル | 任意(以下は test_table を例とする) |
| 特徴的カラム |
REF, SAB(全件異なる値が必要) |
Oracle Database
世界中で広く使われている商用のリレーショナルデータベース管理システム(RDBMS)です。企業の基幹システムなどで多く利用されます。
SQL*Plus
Oracleに標準で付属するコマンドラインツール。SQLやPL/SQLを入力して実行したり、スクリプトの実行、ログの取得ができます。
影響範囲とトラブルの可能性
| 項目 | 内容 | なぜ注意する? |
|---|---|---|
| DB負荷 | 40万件のINSERTは時間がかかり、DBリソースを大量に使う | 遅延や他処理への影響が出るかも |
| トランザクション | 大量の変更はUNDO領域を圧迫し、エラーの原因に | 処理が途中で失敗した時に戻せなくなる可能性 |
| ロック | テーブルロックや行ロックが長時間続くかも | 他のユーザーがテーブルを使えなくなる恐れ |
| 既存データとの整合性 | REF/SABの重複や外部キー違反が起こるかも | データ不整合による障害発生 |
① 上司に作業内容を事前報告する
✅ 伝えるポイント
作業目的(実行計画取得のためのテストデータ投入)
予定件数と作業時間の目安
件数が多いため、影響範囲(DB負荷やロックリスク)と対策案
後で削除可能な設計であること
REF/SABに識別可能な値を入れる(削除しやすい)
実行ログを保存する
💬 報告例
「DBAから実行計画取得目的で40万件のテストデータ追加依頼を受けています。REF/SABに識別可能な値を入れ、後から削除可能な形にします。」
② SQL*Plusでログを保存する(spool)
SPOOL insert_log.txt
このコマンドで、実行中のログが insert_log.txt に保存されます(ファイルはカレントディレクトリに出力されます)。
③ 40万件のINSERTを分割して実行(PL/SQL)
SET SERVEROUTPUT ON
DECLARE
v_ref VARCHAR2(20);
v_sab VARCHAR2(20);
BEGIN
FOR i IN 1..400000 LOOP
v_ref := 'REF' || LPAD(i, 6, '0');
v_sab := 'SAB' || LPAD(i, 6, '0');
INSERT INTO test_table (id, name, ref, sab)
VALUES (i, 'テストユーザー', v_ref, v_sab);
IF MOD(i, 10000) = 0 THEN
DBMS_OUTPUT.PUT_LINE(i || ' 件目まで完了');
COMMIT;
END IF;
END LOOP;
COMMIT;
DBMS_OUTPUT.PUT_LINE('すべてのデータを挿入しました');
END;
補足
LPADで6桁ゼロ埋め → REF000001〜REF400000
理由:後で特定して削除しやすくするため。
COMMITを1万件ごとに実行
理由:UNDO領域の肥大化やロック長期化を防ぐため。
DBMS_OUTPUTで進捗確認できる
④ 実行完了後、件数を確認
SELECT COUNT(*) FROM test_table
WHERE ref LIKE 'REF%' AND sab LIKE 'SAB%';
⑤ 削除用SQLをあらかじめ用意しておく
DELETE FROM test_table
WHERE ref LIKE 'REF%' AND sab LIKE 'SAB%';
COMMIT;
これで40万件を後から安全に削除できます。
⑥ 実行ログをSPOOL OFFして保存
SPOOL OFF
insert_log.txt に、挿入ログ・エラー・進捗メッセージなどが保存されています。
なぜ実行計画の取得のために本番想定データを入れたいのか?
実行計画の精度は「統計情報」に依存します。
統計情報はデータの件数や偏りを反映しており、実際のデータ量に近いほど正確になります。
もしテスト環境のデータ量が少ないと、Oracleは間違った実行計画を選択しやすいです。
本番環境に近いデータを入れることで、現実に即した実行計画が作成でき、SQLのパフォーマンスチューニングや問題分析が正確になります。
重要な用語解説
| 用語 | 意味 | ポイント |
|---|---|---|
| UNDO領域 | データベースのロールバック用の一時領域 | 大量処理で容量を圧迫することがある |
| COMMIT | トランザクション確定の操作 | 定期的に行うことで負荷分散できる |
| SPOOL | SQL*Plusの出力をファイル保存する機能 | 作業ログを残すのに必須 |
| MOD関数 | 割り算の余りを返す | 何件ごとに区切るか判定に使う |
| LIKE 'REF%' | SQL文をどのように処理するかの「設計図」や「手順書」 | REFで始まる文字列を抽出 |
| 実行計画 | 部分一致検索のSQL文法 | Oracleは複数の実行方法を比較し、最も効率的な方法を選ぶ |
| 統計情報 | テーブルの中のデータ件数やカラムの分布など、Oracleがテーブルのデータの状態を把握するための情報 | 実行計画は、この統計情報をもとに作成される |
| アクセスパス | OracleがSQLを実行するときの「処理の道筋」のこと。 | 実行環境(本番、テストなど)でのデータ量や状態が違うと、統計情報も違い、Oracleが選ぶアクセスパスも異なる |
まとめ
| ステップ | 内容 |
|---|---|
| ① | 上司に事前報告&承認 |
| ② |
SPOOLでログ保存開始 |
| ③ | PL/SQLで40万件を安全にINSERT(10,000件ごとにCOMMIT) |
| ④ |
COUNT(*)で件数確認 |
| ⑤ | 削除SQLを事前に用意しておく |
| ⑥ |
SPOOL OFFでログ保存完了 |
おわりに
大量データの投入はDBに影響が大きいので、必ず事前に報告・承認を得ること
トランザクションの分割やログ保存などでリスクを下げることができる
挿入後は必ず件数確認・削除方法も準備すること