Excelファイルの各行に対して生成されたUPDATE
ステートメントがあります。データが変更されているかどうかをチェックします(ファイルには、古い値と新しい値の別々の列があります)。したがって、各ファイルから何十万ものUPDATE
ステートメントを取得します。
この解決策はかなり単純ですが、それを行うより良い方法があるかどうか疑問に思いますか?
これを行うためのおそらくより高速な方法は次のとおりです。
データベーステーブルのデータを提供するには、 sql loader または[外部テーブル]を使用できます。
http://docs.Oracle.com/database/121/SQLRF/statements_9016.htm#SQLRF01606
create table big_tab(
id number primary key,
value1 number,
value2 number,
value3 number)
;
create table mod_tab(
id number,
value1 number,
value2 number,
value3 number)
;
次に、big_tabに次のデータがあるとします。
SQL> select * from big_tab;
ID VALUE1 VALUE2 VALUE3
1 11 21 31
2 12 22 32
3 13 23 33
4 14 24 34
5 15 25 35
次の値を持つcsvファイルmod_data.csvがある
1,111,121,131 3,113,123,133
これをsqlldr load.ctl DIRECT=true
を使用してテーブルにロードするには、次を含むSQLローダー制御ファイルsql.ldrを使用します。
LOAD DATA
INFILE "mod_data.csv"
TRUNCATE
INTO TABLE mod_tab
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
TRAILING NULLCOLS
(
id char,
value1 char,
value2 char,
value3 char
)
オプション「DIRECT = true」を使用すると、このオプションを使用しない場合の読み込みが速くなります。今あなたは持っています
SQL> select * from mod_tab; ID VALUE1 VALUE2 VALUE3 ---------- --------- ----------- ---------- 1 111 121 131 3 113 123 133
これを次のステートメントでbig_tabにマージできます
MERGE INTO big_tab
using mod_tab on (big_tab.id=mod_tab.id)
when matched then update
set
value1=mod_tab.value1,
value2=mod_tab.value2,
value3=mod_tab.value3
;
そして得る
SQL> select * from big_tab; ID VALUE1 VALUE2 VALUE3 ---------- --------- ----------- ---------- 1 111 121 131 2 12 22 32 3 113 123 133 4 14 24 34 5 15 25 35
処理に問題がなければ、クリーンアップできます
truncate table mod_tab;
変更するデータが多い場合は、さらに良い方法があります(少なくともioシステムが高速の場合)。
これは次のスクリプトで実行できます
create table aux_tab as select * from big_tab where 1=0;
alter table mod_tab add primary key (id);
insert /*+ APPEND */ into aux_tab select big_tab.id id,
decode(mod_tab.id,null,big_tab.value1,mod_tab.value1) value1,
decode(mod_tab.id,null,big_tab.value2,mod_tab.value2) value1,
decode(mod_tab.id,null,big_tab.value3,mod_tab.value3) value3
from big_tab, mod_tab
where big_tab.id=mod_tab.id(+)
;
drop table big_tab;
rename aux_tab to big_tab;
alter table big_tab add primary key (id);
alter table mod_tab drop primary key;
truncate table mod_tab;
ロードと挿入は常にダイレクトパスmodで行う必要があります。したがって、APPEND
ヒントを挿入ステートメントに追加し、DIRECT=true
オプションをSQL * Loaderコマンドに追加しました。しかし、いくつかのアクションを並列化してさらに高速化することもできます。並列ステートメントはパーティションテーブルで最適に機能するため、 partition big_tabだけでなく、mod_tabおよびaux_tabも有効です。
何千もの更新の代わりに、データを一時的なソーステーブルに挿入してから、ターゲットテーブルに対してマージを実行できます。
merge into target_table t
using source_table s
on (t.id = s.id)
when matched then update set t.column1 = s.column1, t.column2 = s.column2, ...;
明らかに、その多くの行をExcelなどのツールにエクスポートすることは、通常のアクションのように聞こえるものに対する最悪の解決策のように聞こえます。これはデータの更新です。
冒頭の投稿では、データがOracleデータベースを離れなければならない理由は見当たらない。確かにExcelのようなツールではありません。