2017-01-05 10 views
0

私はテーブルに存在するレコードを検証する必要があります。最初にレコードをテーブルにロードしてから、SQLクエリを使用して検証します。私は状態コードを更新するために以下のクエリを使用していますが、114000を処理するには約7時間かかりました。それは受け入れられますか?なぜそれが時間がかかりすぎるのか分かりません。時間を最小限に抑えるために、より良いアイデアを提案してください。oracleで操作へのマージを実行中の長い実行時間

問合せ:

MERGE INTO mem_src_extn t USING 
( 
SELECT mse.rowid row_id, 
     CASE WHEN mse.type_value IS NULL OR mse."TYPE" IS NULL OR mse.VALUE_1 IS NULL or mse.VALUE_2 IS NULL THEN '100' 
      WHEN (SELECT count(*) FROM cmc_mem_src cms WHERE cms.tn_id = mse.type_value) = 0 THEN '222' 
      WHEN count(mse.value_1) over (partition by type_value) > 1 THEN '333' 
     ELSE '000' int_value_1 
FROM mem_src_extn mse 
) u 
ON (t.rowid = u.row_id) 
WHEN MATCHED THEN UPDATE SET t.int_value_1 = u.int_value_1 

答えて

0

パフォーマンスの問題は、おそらくSELECT count(*)サブクエリ、ないMERGEによって引き起こされます。

MERGEは、ROWIDの結合を使用します。これは、結合が取得できる程度の速さでなければなりません。しかし、Oracleがサブクエリを誤って最適化している可能性があります。

MERGE INTO mem_src_extn t USING 
( 
SELECT DISTINCT 
     mse.rowid row_id, 
     CASE WHEN mse.type_value IS NULL OR mse."TYPE" IS NULL OR mse.VALUE_1 IS NULL or mse.VALUE_2 IS NULL THEN '100' 
      WHEN cms.tn_id IS NULL THEN '222' 
      WHEN count(mse.value_1) over (partition by type_value) > 1 THEN '333' 
     ELSE '000' END int_value_1 
FROM mem_src_extn mse 
LEFT JOIN cmc_mem_src cms 
     ON mse.type_value = cms.tn_id 
) u 
ON (t.rowid = u.row_id) 
WHEN MATCHED THEN UPDATE SET t.int_value_1 = u.int_value_1; 

しかし、これは推測です:相関サブクエリの代わりに LEFT JOINと文を再書き込みしてみてください。私が間違っている場合、次のステップはクエリプランを取得することです。 explain plan for merge ...を実行してから select * from table(dbms_xplan.display);を実行し、その文の出力全体を質問に投稿してください。

関連する問題