概要
oracleのデータ取り込みツールであるSQLLoaderを使って、
1000万件のcsvデータを取り込み、処理ができるか、速度に問題がないかを確認しました。
テーブル定義
テーブル定義については、以下のSQLで作った、
3カラムの単純な構成のテーブルです。
CREATE TABLE EMPLOYEE
(
ID NUMBER(16),
NAME VARCHAR(128),
CREATE_DATE DATE
)
;
ctlファイル
ctlファイルでは、以下の仕様で使います。
OPTIONS(SKIP=0,ERRORS=2147483648,ROWS=1000, DIRECT=TRUE)
LOAD DATA
INFILE 'data.csv'
BADFILE 'data.bad'
TRUNCATE
INTO TABLE EMPLOYEE
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '"'
TRAILING NULLCOLS
(
ID,
NAME,
CREATE_DATE EXPRESSION "SYSDATE"
)
大量データのインポートとして、重要なところとしては、以下の2点。
- ROWS=1000
上記オプションでは、コミットを1000件ごとに行います。
ある程度の単位でまとめてコミットする方針です。
- DIRECT=TRUE
上記は、ダイレクトパスロードと呼ばれる、高速に処理するインポート方法です。
色々制約があったりしますが、今回はこれで行います。
詳細はリファレンスにしっかり記載されています。
1000万件のcsvデータの作成
作成手順は以下で行いました。
- エクセルで最大約100万行のデータを作れるので、まず100万件のcsvをオートフィルなどで一気に作る
- そのあと、作成したcsvファイルをテキストエディタで開き、100万件をコピー貼り付けで複製して作成
実行結果
実行結果のログは以下の通り。
ロード数: ALL
スキップ数: 0
許容エラー数: 2147483648
継続文字: 指定なし
使用パス: ダイレクト
表EMPLOYEE、 ロード済 すべての論理レコードから
この表に対する有効な挿入オプション: TRUNCATE
TRAILING NULLCOLSオプションは有効です。
列名 位置 長さ 用語暗号化データ型
------------------------------ ---------- ----- ---- ---- ---------------------
ID FIRST * , O(")CHARACTER
NAME NEXT * , O(")CHARACTER
CREATE_DATE EXPRESSION
列のSQL文字列 : "SYSDATE"
表EMPLOYEE:
10000000 行は正常にロードされました。
0 行はデータ・エラーのためロードされませんでした。
0 行は、すべてのWHEN句が失敗したためロードされませんでした。
0 行はすべてのフィールドがNULLであったためロードされませんでした。
バインド配列サイズはダイレクト・パスで使用されません。
列配列の行数: 1000
ストリーム・バッファのバイト数: 256000
読取りバッファのバイト数: 1048576
スキップされた論理レコードの合計: 0
読み込まれた論理レコードの合計: 10000000
拒否された論理レコードの合計: 0
廃棄された論理レコードの合計: 0
SQL*Loaderのメイン・スレッドによってロードされたストリーム・バッファの合計: 10237
SQL*Loaderのロード・スレッドによってロードされたストリーム・バッファの合計: 0
実行開始土 11月 20 19:36:33 2021
実行終了土 11月 20 19:37:23 2021
実行時間: 00: 00: 49.78
CPU時間 : 00: 00: 14.58
1000万件インポート処理の時間は50秒程度。
今回は、カラム数が少ないので、増やしたり、他の条件式などを追加したらこれに処理時間がプラスされそうです。