技術ブログ
Oracle Database 12cよりSQL*Loader にExpress Modeと呼ばれる制御ファイルなしで データを簡単にローディングできる手段が提供されました。使用方法は簡単でsqlldrにTABLEパラメータを指定するだけです。
SQL> CREATE TABLE EMP 2 (EMPNO number(4) not null, 3 ENAME varchar2(10), 4 HIREDATE date, 5 DEPTNO number(2)); 表が作成されました。
[oracle@l63x64a tmp]$ cat emp.dat 7782,Clark,81-06-09,10 7839,King,81-11-17,12
パラメータ値と同名のテーブルとCSVファイルを用意しておくと、以下のコマンド 一発でロードが可能です。摩訶不思議なSQL*Loadre制御ファイルの文法と格闘しなくてもよいので、 個人的ななかなかうれしい新機能です。
[oracle@l63x64a tmp]$ sqlldr rywatabe/rywatabe TABLE=emp SQL*Loader: Release 12.1.0.1.0 - Production on 火 8月 20 05:21:15 2013 Copyright (c) 1982, 2013, Oracle and/or its affiliates. All rights reserved. エクスプレス・モード・ロードの表: EMP 使用パス: 外部表, DEGREE_OF_PARALLELISM=AUTO 表EMP: 2行のロードに成功しました。 確認するログ・ファイル: emp.log emp_%p.log_xt ロードの詳細を参照してください。
ログファイルを覗いていみるとちょっと面白いことがわかります。
[oracle@l63x64a tmp]$ cat emp.log SQL*Loader: Release 12.1.0.1.0 - Production on 火 8月 20 05:24:38 2013 Copyright (c) 1982, 2013, Oracle and/or its affiliates. All rights reserved. エクスプレス・モード・ロードの表: EMP データファイルemp.dat 不良ファイル: emp_%p.bad 廃棄ファイル: 指定なし (すべて廃棄できます) ロード数: ALL スキップ数: 0 許容エラー数: 50 継続文字: 指定なし 使用パス: 外部表 表EMP、 ロード済 すべての論理レコードから この表に対する有効な挿入オプション: APPEND 列名 位置 長さ 用語暗号化データ型 ------------------------------ ---------- ----- ---- ---- --------------------- EMPNO FIRST * , CHARACTER ENAME NEXT * , CHARACTER HIREDATE NEXT * , DATE "RR-MM-DD" DEPTNO NEXT * , CHARACTER 可能性のある再使用のために生成された制御ファイル: OPTIONS(EXTERNAL_TABLE=EXECUTE, TRIM=LRTRIM) LOAD DATA INFILE 'emp' APPEND INTO TABLE EMP FIELDS TERMINATED BY "," ( EMPNO, ENAME, HIREDATE DATE, DEPTNO ) 可能性のある再使用のために生成された制御ファイルの終わり。 一時ディレクトリ・オブジェクトSYS_SQLLDR_XT_TMPDIR_00000がパス/var/tmpに対して作成されました パラレルDML: ALTER SESSION ENABLE PARALLEL DMLを有効化します 外部表"SYS_SQLLDR_X_EXT_EMP"を作成しています CREATE TABLE "SYS_SQLLDR_X_EXT_EMP" ( "EMPNO" NUMBER(4), "ENAME" VARCHAR2(10), "HIREDATE" DATE, "DEPTNO" NUMBER(2) ) ORGANIZATION external ( TYPE oracle_loader DEFAULT DIRECTORY SYS_SQLLDR_XT_TMPDIR_00000 ACCESS PARAMETERS ( RECORDS DELIMITED BY NEWLINE CHARACTERSET AL32UTF8 BADFILE 'SYS_SQLLDR_XT_TMPDIR_00000':'emp_%p.bad' LOGFILE 'emp_%p.log_xt' READSIZE 1048576 FIELDS TERMINATED BY "," LRTRIM REJECT ROWS WITH ALL NULL FIELDS ( "EMPNO" CHAR(255), "ENAME" CHAR(255), "HIREDATE" CHAR(255) DATE_FORMAT DATE MASK "RR-MM-DD", "DEPTNO" CHAR(255) ) ) location ( 'emp.dat' ) )REJECT LIMIT UNLIMITED INSERT文を実行してデータベース表EMPをロードしています INSERT /*+ append parallel(auto) */ INTO EMP ( EMPNO, ENAME, HIREDATE, DEPTNO ) SELECT "EMPNO", "ENAME", "HIREDATE", "DEPTNO" FROM "SYS_SQLLDR_X_EXT_EMP" 外部表"SYS_SQLLDR_X_EXT_EMP"を削除しています 表EMP: 2行のロードに成功しました。 実行開始火 8月 20 05:24:38 2013 実行終了火 8月 20 05:24:39 2013 実行時間: 00: 00: 01.02 CPU時間 : 00: 00: 00.03
見ての通りデータファイルが配置されているディレクトリに一時ディレクトリオブジェクトを作成し、データファイルをデータソースに指定した外部表を作成し、INSERT AS SELECTでデータをローディングしているようです。このデータローディング方法の方が、SQL*Loaderダイレクトパスロードよりも高速ということでしょうか? 興味深いためメモしておきます。