2016-06-10 2 views
0

삭제 SQL 스크립트는 오랜 시간이 걸리며 오라클 12c에서도 영원히 매달려 있습니다. 우리는 아래와 같이 수백 개의 삭제 스크립트를 가지고 있으며 병렬 작업/* + 병렬 (a, 4) * /로 실행하려고 시도했지만 성능 향상에는 별 도움이되지 않습니다.SQL 삭제 - 영구 사용

  1. 삭제 스크립트를 조정할 수있는 방법이 있습니까?
  2. 성능 향상을 위해 PL/SQL - for 루프를 사용할 수 있습니까?
  3. 예인 경우 의견 및 조언을 공유하십시오.

샘플 SQL 스크립트의 일부 :

DELETE 
FROM 
E_PROJ_DETAIL 
WHERE 
CATEGORY_ID in (SELECT PRIMARY_KEY FROM Y_OBJ_CATEGORY WHERE TREE_POSITION='VEN$_MADD'); 

COMMIT; 

delete 
from 
e_proj_group_access 
where enterprise_object_id in (select primary_key from t_project where application_id in (select application_id from y_object_definition where unique_code ='VEN$_MADD')); 

commit; 
+2

y_obj_category의 행 수, e_proj_detail의 사용자 수는 어떻게됩니까? category_id에 색인이 있습니까? 당신이해야 할 일은 실행 계획을 보는 것입니다. – Hogan

+2

세부 사항이 없으면 대답하기가 힘듭니다 (아마도 제공 할 수는 없을 것입니다). 내 즉각적인 생각 : 1) 색인 문제가 있습니다. 2) 누군가가 어딘가에 물건을 늦추는 트리거를 구현했습니다. – Paulb

+3

@ Paulb의 추측과 관련하여 인덱싱되지 않은 외래 키 (인덱스 문제 유형이지만 별도로 호출해야하는 항목)가 있는지에 대한 질문이 될 것입니다. –

답변

0

내가 '조정'에 대한 모든 가능성에 대해 모른다는 어쩌면 선행 어떤 쓸모없는 (= 사용하지 않는) 인덱스와 제약을 떨어 뜨릴 그들을 다시 제외하고, DELETE 문 나중에.

I := 0; 
FOR c IN (SELECT id FROM table WHERE [conditions to delete]) 
LOOP 
    DELETE FROM table WHERE t.id = c.id; /* id = primary key */ 
    IF (I > 1000) THEN 
     COMMIT; 
     I := 0; 
    END IF; 
    I := I + 1; 
END LOOP; 

그러나 여기 당신이에서 같은 테이블에서 행을 삭제하기 때문에 가끔, ORA-01555: snapshot too old으로 실행할 수 있습니다, 내부 이런 일을 저지른 이러한 경우 (많은 행을 h)에서

나는 FOR 루프를 사용 어떤 커서를 FOR 루프에 열었습니다.

다른 상황에서는 CREATE TABLE newtable AS SELECT * FROM oldtable WHERE [conditions for rows I want to keep]을 수행 한 다음 TRUNCATE oldtableINSERT /*+ APPEND */ INTO oldtable SELECT * from newtable;으로 올바른 데이터를 다시 쓸 수 있습니다.

정말 상황에 따라 다릅니다 (다른 사람이 주석을 달았습니다 - 테이블에있는 행 수, 삭제하려는 행 수 등).

:-) HTH

0

훨씬 더 빨리 자주 유지하려는 경우에만 행에 새 테이블을 생성한다 그것은 하나의 샷 거래 인 경우 따라 여부 :

CREATE TABLE E_PROJ_DETAIL_NEW AS 
SELECT * FROM 
E_PROJ_DETAIL 
WHERE 
CATEGORY_ID NOT IN (SELECT PRIMARY_KEY FROM Y_OBJ_CATEGORY WHERE TREE_POSITION='VEN$_MADD'); 

그런 다음 삭제 새 테이블의 이름을 바꿉니다.

인덱스/fk가 ​​있으면 다시 만들어야 할 수도 있습니다.