読者です 読者をやめる 読者になる 読者になる

kagamihogeの日記

kagamihogeの日記です。

SQL*Loaderさわる

DB Oracle SQL*Loader

SQL*Loaderマッタク使ったことないんで、とりあえず使ってみる。

参考:
Oracle Databaseユーティリティ11g リリース1(11.1)第II部 SQL*Loader

準備

下記の単純なテーブルにデータを入れていく。

CREATE TABLE DEST (COLUMN1 VARCHAR2(16));

やったこと

従来型パスロードとダイレクト・パスロードの速度を比較

参考:
Oracle Databaseユーティリティ11g リリース1(11.1)11 従来型パス・ロードおよびダイレクト・パス・ロード

SQL*Loader起動用のバッチファイルはこんな感じ。

C:\oraclexe\app\oracle\product\11.2.0\server\bin\sqlldr.exe kagamihoge/xxxx@XE2 CONTROL=fix_data.ctl LOG=fix_data.log BAD=fix_data.bad skip=0

制御ファイルはこんな感じ。ダイレクトパスなのでOPTIONSにソレを指定、insert指定で毎回テーブルはDROP&CREATE、とりあえず固定レコード形式、でやる。

OPTIONS (DIRECT=TRUE)
load data 
infile 'fix_data.dat' "fix 16"
insert
into table DEST
fields terminated by ','
(COLUMN1 CHAR(16))

入力データ。ただの乱数文字列。固定レコード形式で改行無いんで見辛いですが、16バイトごとに1レコードになります。百万行分用意。以下、入力データはすべて百万行です。

TWALmkkeWjZkPSqfFeXzibFJxESGnBtozNJXGVmWUpIAafGQ(以下略)

従来型の方の制御ファイル。OPTIONSを消しただけ。

load data 
infile 'fix_data.dat' "fix 16"
insert
into table DEST
fields terminated by ','
(COLUMN1 CHAR(16))

で、結果の実行時間。

(00秒00の形式) 1 2 3
ダイレクトパス 02.02 01.86 01.37
従来型(ROWS=64) 27.01 25.15 24.60
従来型(ROWS=1000) 04.84 04.59 04.99

三行目は、OPTIONS (ROWS=1000)を指定したもの。二行目は、デフォルトのまま実行したもので、ROWSの値は64。これはSQL*Loaderの実行ファイルをパラメータ無しで実行したときに表示されるデフォルト値をそのまま載せているだけ。

ダイレクトパス速いっつーのと、従来型でやる場合でもコミット間隔調整すれば速くなる、ってのが分かります。

データファイルの形式の違いによる速度の差はあるか

リファレンスによると下記のような記述がある。よほどややこしい入力ファイルで無い限り差は特に出ないと思われるが、とりあえずはタブン差が出ないであろうことを確かめてみる。

固定レコード形式(中略)この形式は柔軟性はありませんが、その結果、可変長またはストリーム形式よりも高いパフォーマンスを得ることができます。
可変レコード形式(中略)固定レコード形式より柔軟性があり、ストリーム・レコード形式よりパフォーマンスに優れています。
ストリーム・レコード形式(中略)ストリーム・レコード形式は最も柔軟性のある形式ですが、パフォーマンスに影響する場合があります。
Oracle Databaseユーティリティ11g リリース1(11.1)6 SQL*Loaderの概念 入力データおよびデータ・ファイル より抜粋

固定レコード形式はさっきやったんで省略。

可変レコード形式の制御ファイル。infileを変更している以外、このエントリの上の方でやった固定レコード形式のものと変わらない。

OPTIONS (DIRECT=TRUE)
load data 
infile 'var_data.dat' "var 3"
insert
into table DEST
fields terminated by ','
(COLUMN1 CHAR(16))

可変レコード形式の入力データ。

016mmqdJMVaZUPoPaFN016JhHoSwfoKMdlmUFp016XHIquFxtdnZYJpHv(以下略)

ストリーム・レコード形式の制御ファイル。

OPTIONS (DIRECT=TRUE)
load data 
infile 'stream_data.dat' "str"
insert
into table DEST
fields terminated by ','
(COLUMN1 CHAR(16))

ストリーム・レコード形式の入力データ。

SGRUPXcbHZRLuoUd
rsrEEHfCMkFqTtlx
hfQdfXsyyNYfrJnd
(以下略)

で、結果の実行時間。

(00秒00の形式) 1 2 3
固定レコード 02.02 01.86 01.37
可変レコード 01.50 01.51 01.57
ストリームレコード 02.99 01.67 01.62

というわけで、単一行からなるごくごく単純な入力ファイルでは、入力ファイルのレコード形式による差はそんなに見られなかった。気のせいレベル(0.1秒〜0.5秒)では、固定レコードの方が速いかな? 程度の差はある。が、ダイレクトパスそのものが速くて、その他の要因で0.x秒レベルはぶれるので、この単純な入力ファイルのケースだと差は無いと言って良い気がする。千万とか億とかのオーダーまで行くと、文字列解析のCPU時間も無視できなくなっちゃったりするんですかね。