外部表を触ってみた(ORGANIZATION EXTERNAL)
http://www.oracle.co.jp/iSeminars/071120_1600/doc/DataLoading_071120.pdf
この辺に触発されて
・外部表
・テーブル圧縮(COMPRESS)
の2つを試して見たくなった。
COMPRESSについてはEEでのみ使える機能とのことなので会社の開発環境にて試そうと思うが
今回は外部表を触ってみた。
とりあえず
http://www.shift-the-oracle.com/table/external-table-practice.html
を見ながらDirectory
CREATE DIRECTORY CSV AS 'c:\csv';
と外部表のTableを作ってみた。
CREATE TABLE DL_CSV ( DLDATE DATE, MID NUMBER, DLCOUNT NUMBER) ORGANIZATION EXTERNAL( TYPE ORACLE_LOADER DEFAULT DIRECTORY csv ACCESS PARAMETERS( RECORDS DELIMITED BY NEWLINE FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ( DLDATE CHAR DATE_FORMAT DATE MASK 'YYYY/MM/DD', MID, DLCOUNT ) ) LOCATION( 'dl.txt' ) );
動作確認できたのでSQLLoaderとの比較をしてみる。
dl.txt:900,000件
処理:DLDATE,MID,DLCOUNTをDLDATE,DLCOUNTへ集計
集計テーブルはこんな感じ
CREATE TABLE DAILY_DL( DLDATE DATE, DLCOUNT NUMBER );
まずは外部表から
さっき作った外部表からselectinsertしてみる
INSERT INTO DAILY_DL SELECT DLDATE ,SUM(DLCOUNT) DLCOUNT FROM DL_CSV GROUP BY DLDATE
結果15秒くらい
次にSQLLoaderで試してみる
まずコントロールファイル作成
LOAD DATA INFILE 'c:\csv\dl.txt' BADFILE 'c:\csv\dl.bad' TRUNCATE INTO TABLE DL_LDR FIELDS TERMINATED BY "," ( DLDATE "TO_DATE(:DLDATE,'YYYY/MM/DD')", MID, DLCOUNT )
でロードしてみたところ2分50秒かかった
まぁ、外部表の時と違って1レコード単位でInsertしてるのでしょうがないか。。。
んで、selectinsert
INSERT INTO DAILY_DL SELECT DLDATE ,SUM(DLCOUNT) DLCOUNT FROM DL_LDR GROUP BY DLDATE
ここで4秒 = 約3分
結果
外部表:15秒
ローダー:3分
どうも、ローダーの場合は1行1行Insertしてて分が悪いようなので外部表でも実テーブルへ全行Insertしてみた。
INSERT INTO DL_LDR SELECT * FROM DL_CSV
結果28秒
おーすごいですね。
ちなみにダイレクトパスインサートもできるみたいなのでついでに試して見た。
INSERT /*+APPEND*/ INTO DL_LDR SELECT * FROM DL_CSV
結果14秒 半分になりました。
これは使えるかもしれない!!