2017-12-08 1 views
1

올바른 레코드를 찾기 위해 여러 테이블을 조인하여 한 테이블의 일부 레코드를 업데이트해야한다는 복잡한 요구 사항이 있습니다. 나는 작동하고있는 다음 질의를 작성했지만 2.5 분 정도 걸리므로 DB 연결 시간 초과가 발생합니다. 이 쿼리를 다시 작성하여 효율성을 향상시킬 수있는 방법이 있습니까? 나는 또한 너무 오래 걸리는 MERGE 접근법을 시도했다. EVENT_DYNAMIC_ATTRIBUTE 테이블에 2 백만 개 이상의 레코드가 있고 EVENT 테이블에 1 백만 개의 레코드가 있고 CATEGORY 테이블에 10 만 개의 레코드가 있습니다. 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 아마 난 항상 이런 상황에서 시도 할 수 있는지 확인이 – GurV

+0

뭔가를 달성하기 위해 가장 좋은 방법은 절을 사용하여 계수를 시도 할 수는있는 ed.rowid' BY'ORDER하는 것입니다 '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 오류 [1879] : [42000] : 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