約700,000件のレコードがあるテーブルに対して一括更新を実行しようとしています。実効開始日を前のレコードの有効終了日で更新する必要があります。サブクエリを使用しているときに、更新ステートメントのパフォーマンスに問題があります。日付(7/1/2016-7/15/2016、約2kレコード)のフィルターでも1時間以上実行されます。私は単純な更新ステートメントとして、挿入として、そしてループで試しました。 account_dim_key(テーブルのPK)の代わりにROWIDを使用するEXPLAIN PLANははるかに最適ですが、サブクエリが複数の行を返すというエラーが発生します。なぜ私はROWIDでそれが起こっているのか分かりません。一括更新の開始日は前の終了日を基準にします
IDは、テーブル上の自然なキーですが、account_dim_keyはPKで一意です。両方とも索引付けされます。表はタイプ2のSCDです。私は
- その
UPDATEステートメントは、複数の行を返すが、最適とNとacocunt_dim_key使用
UPDATE DEXWHS.D_ACCOUNT_VEEVA
SET effective_end_dt =
(SELECT prev_dt
FROM (SELECT LAG (
effective_end_dt,
1,
effective_start_dt)
OVER (PARTITION BY account_dim_key
ORDER BY effective_start_dt)
AS prev_dt,
ROWID AS rid
FROM dexwhs.d_account_veeva ac2) a
WHERE a.rid = ROWID)
UPDATEステートメントプラン説明しますaccount_dim_key
が主キーである場合に最適な、それは全体のテーブルを更新しているので、クエリはいくつかの時間を取る必要がありますMERGE
MERGE INTO dexwhs.d_account_veeva a
USING (
SELECT account_dim_key,
LAG (effective_end_dt, 1, effective_start_dt)
OVER (PARTITION BY account_dim_key
ORDER BY effective_start_dt)
AS prev_dt
FROM dexwhs.d_account_veeva
) b
ON (a.account_dim_key = b.account_dim_key)
WHEN MATCHED THEN UPDATE SET a.effective_end_dt = b.prev_dt
を試し、その後、ループ
CREATE OR REPLACE PROCEDURE PREV_UPDT
IS
CURSOR c1
IS
SELECT account_dim_key,
id,
active_flag,
effective_end_dt,
effective_start_dt,
created_date,
last_modified_date,
(SELECT prev_dt
FROM (SELECT LAG (
effective_end_dt,
1,
effective_start_dt)
OVER (
PARTITION BY id
ORDER BY effective_start_dt, account_dim_key)
AS prev_dt,
account_dim_key AS rid
FROM dexwhs.d_account_veeva ac2) a
WHERE a.rid = src.account_dim_key)
FROM dexwhs.d_account_veeva src
ORDER BY id, effective_start_dt, account_dim_key;
r1 c1%ROWTYPE;
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO r1;
EXIT WHEN c1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE ('id=' || r1.id);
UPDATE dexwhs.D_ACCOUNT_VEEVA trgt
SET trgt.effective_start_dt = r1.prev_date,
trgt.audit_last_update_dt = SYSDATE,
WHERE trgt.account_dim_key = r1.account_dim_key;
DBMS_OUTPUT.PUT_LINE ('r1.id_found');
END LOOP;
CLOSE c1;
END