株式会社コーソル

コーソルDatabaseエンジニアのブログ

技術ブログ

SQL*Loader Express Modeと外部表

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ダイレクトパスロードよりも高速ということでしょうか? 興味深いためメモしておきます。

プロフィール

On7tWW6m1Ul4

渡部 亮太

・Oracle ACE
・AWS Certified Solutions Architect - Associate
・ORACLE MASTER Platinum Oracle Database 11g, 12c 他多数

カテゴリー

アーカイブ