2017-11-27 20 views
0

同じスクリプト内の以前の同様の更新が約1時間で終了したときにハングするOracle Updateステートメントがあります。Oracle Updateステートメントがハングする

表A:ID、Masked_Account、Original_Account(9+万行、相互参照表)

私は2つのテーブルを持っています。

表B:UID、Prefix_Pan、Pan、Masked(13億行以上)。

テーブルBのパン列がテーブルAのMasked_Account列でテーブルBのパン列がaTable A Original_Account列と一致する各インスタンスで更新しようとしています。

バッチごとに1億回のバッチで更新を行い、その後コミットします。

UPDATE [TABLE B] optim 
SET optim.PAN = (SELECT MASKED_ACCOUNT FROM [TABLE A] pans 
       WHERE optim.PAN = pans.ORIG_ACCOUNT), optim.MASKED = '1' 
WHERE optim.OPTIM_UID > 1300000000 
AND EXISTS (SELECT 1 
      FROM [TABLE A] pans 
      WHERE optim.PAN = pans.ORIG_ACCOUNT); 

プラン(DBMS_XPLAN.DISPLAYを)説明:

UPDATE [TABLE B] optim 
SET optim.PAN = (SELECT MASKED_ACCOUNT FROM [TABLE A] pans 
       WHERE optim.PAN = pans.ORIG_ACCOUNT), optim.MASKED = '1' 
WHERE optim.OPTIM_UID BETWEEN 1200000000 AND 1300000000 
AND EXISTS (SELECT 1 
      FROM [TABLE A] pans 
      WHERE optim.PAN = pans.ORIG_ACCOUNT); 

私の最後の更新のSQLステートメントがハングし、決して終了しません:たとえば

は、以下の更新SQLスクリプトは約1時間で終了した記載されています結果:

Plan hash value: 4037184420 

---------------------------------------------------------------------------------------------------------------------- 
| Id | Operation        | Name       | Rows | Bytes | Cost (%CPU)| Time  | 
---------------------------------------------------------------------------------------------------------------------- 
| 0 | UPDATE STATEMENT      |        | 250 | 9250 | 465K (1)| 00:00:10 | 
| 1 | UPDATE        | OPTIM_SMRY_FTR_CHKMC_EXTRACT |  |  |   |   | 
|* 2 | HASH JOIN RIGHT SEMI    |        | 250 | 9250 | 239K (1)| 00:00:05 | 
| 3 | INDEX STORAGE FAST FULL SCAN  | IDX_PANS_ORIG_ACCT   | 82 | 902 | 1(1)| 00:00:01 | 
| 4 | TABLE ACCESS BY INDEX ROWID BATCHED| OPTIM_SMRY_FTR_CHKMC_EXTRACT | 32M| 796M| 228K (1)| 00:00:05 | 
|* 5 |  INDEX RANGE SCAN     | PK_OP_47      | 22M|  | 53465 (1)| 00:00:02 | 
| 6 | TABLE ACCESS BY INDEX ROWID BATCHED | PANS       |  1 | 22 | 604 (1)| 00:00:01 | 
|* 7 | INDEX RANGE SCAN     | IDX_PANS_ORIG_ACCT   |  1 |  |  3 (0)| 00:00:01 | 
---------------------------------------------------------------------------------------------------------------------- 

Predicate Information (identified by operation id): 
--------------------------------------------------- 

    2 - access("OPTIM"."PAN"="PANS"."ORIG_ACCOUNT") 
    5 - access("OPTIM"."OPTIM_UID">1300000000) 
    7 - access("PANS"."ORIG_ACCOUNT"=:B1) 

Note 
----- 
    - dynamic statistics used: dynamic sampling (level=AUTO) 

誰もが、私はリットルで異なる何をする必要があるかを教えてもらえますast SQL(optim.OPTIM_UID> 1300000000)を更新して、ハングしないようにするか、Updateプロセス全体にどのようにアプローチする必要がありますか?

+0

多くの質問があります。 1200000000から1300000000の間に実際に100ミリの行がありますか?私の推測はノーです。おそらく1300000000を超える行があります。ブロックロックを確認しましたか?一緒に動いているようですか? (元に戻す/ロールバックを使用して)dbasは何を言いますか? – tbone

+0

実際には、1200000000から1300000000の間に1億の行があります。Optim_UIDは実際には 'rownum'です。表Bの総行数は1,322,566,115です。最後のUpdateバッチ(> 1300000000)を実行しようとした最後の時間に、ブロックされたロックは見られませんでしたが、22時間以上実行されていました。現在、他のより高い優先順位のためにdbasを​​見ることができません。 –

+0

13億回の更新があり、それぞれにはmasked_accountのサブクエリが必要です。そして、私はこれのEXISTS部分が各行に対しても発火すると信じています。 2つのテーブルをジョインして作業テーブルに挿入する方が速いかもしれませんか?次にドロップして名前を変更しますか?最初に無効にできるoptim.PANのインデックスはありますか? – Stilgar

答えて

1

は述語optim.masked列は、それがマスクされた後にのみ1に設定されているようですね

で相関サブクエリを使用する代わりにOPTIM.MASKED列に依存しています。デフォルト動作を知ることが理想的です。

- NULLに設定できますか?

- デフォルトでは0に設定されていますか?

- この列にはどのような制約がありますか?

(述語で相関サブクエリを削除)NULLに設定することができ、それがマスクされた後、それが唯一の1に設定されている、あなたがこれを行うことができませんでしたと仮定:

UPDATE [TABLE b] optim 
SET optim.pan = (SELECT masked_account FROM [TABLE A] pans 
       WHERE optim.pan = pans.orig_account), 
    optim.masked = '1' 
WHERE optim.masked != '1' 
OR optim.masked IS NULL; 

このアプローチがあることを前提としてい述語内の相関サブクエリは、パフォーマンスとロックの問題の原因です。あなたの文はロックが得られているかどうかを確認する必要があります


は、V $ LOCKED_OBJECTビューを照会して、セッションに関連付けられているロックを探すことです。


我々はoptimテーブルを更新するためにoptim.maskedに頼ることができない場合、私は、相関subqueryingを避けるために、MERGE文を使用して見ます。表Aには、orig_account(マージの確定的機能に必要)のレコードが1つあります。テーブルAのプライマリキーが何であるかを確認することができます。orig_accountがプライマリキーであると仮定します。

MERGE INTO [TABLE b] optim USING [TABLE A] pans ON (optim.pan = pans.orig_account) 
WHEN MATCHED THEN UPDATE SET optim.pan = pans.masked_account, 
optim.masked = '1'; 
関連する問題