2017-12-08 6 views
1

複数のテーブルを結合して正しいレコードを見つけることによって、あるテーブルのレコードを更新するという複雑な要件があります。私は働いている次のクエリを書いたが、それは私のDB接続タイムアウトを引き起こしている実行するために2.5分かかる。それを書き換えることによってこのクエリの効率を向上させる方法はありますか?私はまた、MERGEアプローチも試みましたが、これもまた時間がかかりすぎています。私はEVENT_DYNAMIC_ATTRIBUTEテーブルに200万レコード以上、EVENTテーブルに100万レコード、CATEGORYテーブルに100000レコードを持っています。Oracleの複数のテーブルを結合して効率的な更新クエリを書く

UPDATE EVENT_DYNAMIC_ATTRIBUTE eda 
SET eda.ATTRIBUTE_VALUE = 'claim', 
    eda.LAST_UPDATED_DATE = SYSDATE, 
    eda.LAST_UPDATED_BY = 'superUsers' 
WHERE eda.DYNAMIC_ATTRIBUTE_NAME_ID=4002 
    AND eda.EVENT_ID IN 
    (SELECT e.EVENT_ID 
    FROM EVENT e 
    WHERE e.PRIMARY_CATEGORY_ID IN 
     (SELECT CATEGORY_ID 
      FROM CATEGORY START WITH CATEGORY_ID = 495984 CONNECT BY PARENT_ID = 
      PRIOR CATEGORY_ID)); 

これは、マージクエリです:

MERGE INTO EVENT_DYNAMIC_ATTRIBUTE eda 
    USING (SELECT DISTINCT e.EVENT_ID FROM (
     SELECT CATEGORY_ID 
     FROM CATEGORY 
     START WITH CATEGORY_ID=495984 
     CONNECT BY PARENT_ID = 
     PRIOR CATEGORY_ID) CATEGORIES 
    INNER JOIN EVENT E ON e.PRIMARY_CATEGORY_ID = CATEGORY_ID 
    INNER JOIN EVENT_DYNAMIC_ATTRIBUTE ed on ed.EVENT_ID = E.EVENT_ID) temp 
    ON (eda.EVENT_ID = temp.EVENT_ID) 
    WHEN MATCHED THEN 
     UPDATE SET eda.ATTRIBUTE_VALUE = 'claim', 
        eda.LAST_UPDATED_DATE = SYSDATE, 
        eda.LAST_UPDATED_BY = 'superUser' 
    WHERE eda.DYNAMIC_ATTRIBUTE_NAME_ID=4002 
+0

MERGE WITH使用率を試すことができますが、おそらく私はいつもこのような状況で試してみてください、あなたの中ed.rowid' BY 'ORDERにあることを確認、この – GurV

+0

何かを達成するための最良の方法です'USING'節。結合を使った 'UPDATE'では、多くの助けとなります。結合で' MERGE'を助けるかもしれないと思います。このスレッドを参照してください:https://asktom.oracle.com/pls/asktom/asktom.search?tag=how-to-update-millions-or-records-in-a-table-200211#5402195700346034590私は40-60%の改善を見ました。 –

答えて

0

あなたは

update 
    (
    select 
     eda.* 
    from 
     (select * from event_dynamic_attribute where dynamic_attribute_name_id = 4002) eda, 
     (select category_id from category start with category_id = 495984 connect by parent_id = prior category_id) c, 
     event e 
    where 
     e.primary_category_id = c.category_id and 
     e.event_id = eda.event_id 
) 
set 
    attribute_value = 'claim', 
    last_updated_date = sysdate, 
    last_updated_by = 'superUsers' 

ような何かを試すことができますが、私はそれができます疑います。一般に、古いハードウェア上で動作していても、非常に低速です。あなたはこれらの更新を追跡し、それらの実行など、影響を受けるすべてブロックの

ファーストをチェックする必要があり、私は

explain plan for <<your update statement text>>; 
select * from table(dbms_xplan.display()); 

を実行し、それが問題になるのです書き込みをお願いしたいです。さらに... event_dynamic_attributeテーブルにトリガがありますか?

+0

このアプローチの問題は、私は常にクエリを実行中に次のエラーが発生することです。 SQLエラー[18000]:ORA-01779:キー保存されていないテーブルにマップされている列を変更できません – user1614862

+0

これは、キーが保存されているように見えます。 event_idはイベント用のpkですか?カテゴリのcategory_id? event_dynamic_attributeに主キーがありますか? –

+0

はい、event_idはイベントのpk、category_idはカテゴリのpk、event_dynamic_attribute_idはevent_dynamic_attributeのpkです。 – user1614862

関連する問題