Oracle에서 삭제 문이 매우 느렸습니다.
나는 약 100k의 기록이 있는 테이블을 가지고 있고 몇개의 행을 삭제하고 싶습니다. 문제는.DELETE
진술이 매우 느리게 진행되고 있습니다. 30분 안에 끝나지 않았습니다.하지만.select
문장이 1초만에 돌아왔습니다.
그SELECT
문은 다음과 같습니다.
select * from daily_au_by_service_summary
where summary_ts >= to_date('09-04-2012','dd-mm-yyyy')
order by summary_ts desc;
그리고.DELETE
문은 다음과 같습니다.
delete from daily_au_by_service_summary
where summary_ts > to_date('09-04-2012','dd-mm-yyyy');
이 테이블에는 다음과 같은 유일한 인덱스가 있습니다.summary_ts
.
그 이유는 무엇일까요?
편집: 테이블을 잠그는 세션을 종료한 후 문제가 해결되었습니다. 도움을 주셔서 감사합니다.
SESSION_ID ORACLE_USERNAME OS_USER_NAME OBJECT OWNER OBJECT_NAME OBJECT_TYPE LOCKED_MODE
---------- ------------------------------ ------------------------------ ------------------------------ -------------------------------------------------------------------------------------------------------------------------------- ------------------- -----------
213 T03RPT elou T03RPT DAILY_AU_BY_SERVICE_SUMMARY TABLE 3
203 T03RPT elou T03RPT DAILY_AU_BY_SERVICE_SUMMARY TABLE 3
202 T03RPT elou T03RPT DAILY_AU_BY_SERVICE_SUMMARY TABLE 3
190 T03RPT elou T03RPT DAILY_AU_BY_SERVICE_SUMMARY TABLE 3
189 T03RPT elou T03RPT DAILY_AU_BY_SERVICE_SUMMARY TABLE 3
188 T03RPT elou T03RPT DAILY_AU_BY_SERVICE_SUMMARY TABLE 3
187 T03RPT elou T03RPT DAILY_AU_BY_SERVICE_SUMMARY
여러 가지 이유가 있을 수 있습니다.
- 서버 로드(가능하지 않은 이유는
SELECT
빠름) - 트리거(테이블에 대한 목록을 표시하는 방법 참조).
- 외부 키(외부 키 목록 및 참조 테이블)
- 각 행에 많은 데이터(
LOB
s, 많은 열). - 삭제할 테이블(또는 전체 테이블)의 행을 누군가가 잠그고 있습니다.이 블로그 게시물에서 잠금을 나열하는 방법을 확인할 수 있습니다.이 토론도 도움이 될 것입니다.
외부 키가 문제인 경우 일반적인 해결책은 외부 열에 인덱스를 추가하는 것입니다.삭제할 때마다 Oracle은 외부 키 관계를 위반하는지 확인해야 합니다.
삭제한다는 것은 표의 내용을 변경하는 것을 의미합니다.이는 삭제된 행이 있을 때마다 모든 인덱스가 업데이트되고 모든 외부 키 참조가 확인되어야 함을 의미합니다.이것은 매우 오랜 시간이 걸릴 수 있습니다!
어쩌면 이것이 도움이 될 수도 있습니다.
참조, 트리거 및 추가 인덱스 없이 해당 테이블의 복사본을 만듭니다.그러면 다음을 수행합니다.
insert into new_table (field1, field2, ...) values (
select field1, field2, ...
from daily_au_by_service_summary
where summary_ts < to_date('09-04-2012','dd-mm-yyyy')
);
표의 필드가 동일한 순서로 정의된 경우 다음 작업도 수행할 수 있습니다.
insert into new_table values (
select *
from daily_au_by_service_summary
where summary_ts < to_date('09-04-2012','dd-mm-yyyy')
);
그 후:
truncate daily_au_by_service_summary
그 다음:
insert into daily_au_by_service_summary (field1, field2, ...) values (
select field1, field2, ...
from new_table;
);
새 테이블은 더 이상 필요하지 않습니다.
drop new_table;
분명히 삭제 작업은 선택한 것보다 더 오래 걸리지만, 그것은 여러분이 보는 차이를 고려하지 않습니다.
삭제 시 추가 코드가 실행되고 있는 것처럼 들리므로 테이블에 트리거가 실행되고 있는 것일 수 있습니다.이것 좀 확인해주시겠습니까?
DML 작업에 시간이 오래 걸릴 경우 삭제 대신 남은 행으로 새 테이블을 만들고 이전 테이블을 삭제합니다.
제 말은.
create table NEW_TABLE as
select * from daily_au_by_service_summary
where summary_ts <= to_date('09-04-2012','dd-mm-yyyy');
이는 특히 많은 행을 삭제할 때 더 빠릅니다.(예를 들어 총 행의 %10).
언급URL : https://stackoverflow.com/questions/10101484/delete-statement-was-very-slow-in-oracle
'prosource' 카테고리의 다른 글
UI 레이블의 배경색을 애니메이션화하는 방법은? (0) | 2023.09.25 |
---|---|
AJAX / Jquery XML 구문 분석 (0) | 2023.09.25 |
DLL의 내보낸 기능의 네임 망글링을 중지하려면 어떻게 해야 합니까? (0) | 2023.09.25 |
Android에 프로그래밍 방식으로 응용 프로그램 설치 (0) | 2023.09.25 |
Oracle에서 범위/간격 쿼리를 조정하는 방법은 무엇입니까? (0) | 2023.09.25 |