2010-03-22 2 views
5

이전에는 많은 양의 행이있는 빈 테이블이 있습니다.포어를 가져 오는 빈 테이블에서 삭제

이 테이블에는 약 10 개의 열과 인덱스가 있으며, 다수의 열에는 인덱스가 있습니다.

DELETE FROM item WHERE 1=1 

이이 4 초 정도 걸립니다

SELECT * FROM item 

완료하는 데 약 40 초가 걸립니다.

SELECT * FROM ITEM의 실행 계획은 다음을 보여줍니다.

SQL> select * from midas_item; 

no rows selected 

Elapsed: 00:00:04.29 

Execution Plan 
---------------------------------------------------------- 
0  SELECT STATEMENT Optimizer=CHOOSE (Cost=19 Card=123 Bytes=73 
     80) 

1 0 TABLE ACCESS (FULL) OF 'MIDAS_ITEM' (Cost=19 Card=123 Byte 
     s=7380) 





Statistics 
---------------------------------------------------------- 
     0 recursive calls 
     0 db block gets 
    5263 consistent gets 
    5252 physical reads 
     0 redo size 
    1030 bytes sent via SQL*Net to client 
    372 bytes received via SQL*Net from client 
     1 SQL*Net roundtrips to/from client 
     0 sorts (memory) 
     0 sorts (disk) 
     0 rows processed 

왜 이렇게 오래 걸릴지 그리고 어떻게 고쳐야하는지 모든 아이디어는 크게 감사하겠습니다 !!

+0

이 테이블에 몇 개의 데이터 (행)가 있습니까? – bragboy

+1

외래 키에 의해이 테이블을 참조하는 다른 빈 테이블이 있습니까? – dpbradley

+0

마지막으로 지울 때 표에 약 200k 행이 있습니다. 과거에는 그 이상이었습니다 (아마 2mil diff 행이 평생 동안이었습니다) – Will

답변

2

전체 테이블 스캔을 선택하는 중입니다. 반면에 삭제 (오라클에서)는 삭제 된 전체 행을 롤백 세그먼트에 저장해야만 나중에 변경 사항을 실행 취소 할 수 있으므로 삽입보다 느려질 수 있습니다.

Ask Tom 포럼과 관련하여 매우 길고 유용한 토론을 찾을 수 있습니다. 비즈니스 케이스에 따라 더 많은 기법을 적용 할 수 있습니다.

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:2345591157689

2

테이블에 많은 인덱스가있는 경우 인덱스의 각 항목도 제거해야하기 때문에 삭제에 시간이 걸릴 것입니다. 인덱스는 읽기 프로세스 속도를 높이고 쓰기 또는 기타 수정 프로세스를 느리게 만듭니다 (따라서 빠른 선택).

- 편집 : 죄송합니다. 질문을 완전히 읽지 않았습니다. 테이블이 비어 있으면 인덱스 문제 일 수 없습니다. 그렇지 않으면 놀랄 것입니다. -

+0

글쎄, 셀렉트는 여전히 4 초 정도 걸리는데 그래도 속도는 비슷합니다. – Will

+0

하지만 테이블에 이미 행이 없으므로 DELETE가 인덱스를 수정하면 안됩니다. –

1

테이블에서 모든 행을 정기적으로 삭제하는 경우 'truncate table XXX'는 대개 ​​대량 삭제보다 훨씬 빠릅니다. 어쩌면 그것을 시도하고 얼마나 빨리 얻을 수 있는지보십시오.

+0

True - 그러나 TRUNCATE가 수행하는 작업 (공간 할당을 취소하고 트랜잭션을 커밋)을 이해했는지 확인하십시오. –

+0

나는 모든 행을 삭제하기 위해 truncate를 사용했다. – Will

3

이전에 테이블에 많은 양의 데이터가 채워진 경우 오라클은 데이터가없는 경우에도 상위 워터 마크까지 스캔합니다. TRUNCATE 문을 사용하여 HWM을 재설정 할 수 있습니다.

Also on AskTom

+0

이것은 나의 첫 번째 생각이기도하다. 그러나 왜 DELETE가 SELECT보다 훨씬 느린지를 설명 할 수 있는지 확신 할 수 없다. –

+0

TRUNCATE TABLE을 사용하여 내용을 원래대로 지 웠습니다. 사용 후 느려졌습니다. – Will

4

하나의 가능성은 잠금입니다. 테이블에 다른 삭제에 의해 커밋되고 잠긴 행이 있습니다. 귀하의 삭제가 자물쇠를 기다렸다가 기다렸습니다. 잠금 트랜잭션이 커밋되면 삭제를 완료 할 수있었습니다.

두 번째 가능성은 디스크에서 캐시로 블록을 가져온 삭제를 먼저 실행 한 것입니다 (시간이 걸렸습니다). 선택을 실행하면 데이터가 캐시에 저장되어 더 빨리 실행됩니다. 나는 이것이 "5252 physical reads"라고 표시된 통계를 선택할 때 가능성이 적기 때문에 SGA 캐시에서 가져 오는 것이 아닙니다. 디스크 캐쉬가 포함되었을 수도 있습니다.

세 번째 가능성은 무언가를 한 BEFORE/AFTER DELETE 트리거 (각 행에 해당하지 않음)가 있다는 것입니다.

네 번째 가능성은 DELETE가 지연된 블록 정리를 초래한다는 것입니다. 행이 실제로 삭제되면 커밋되기 전에 디스크에 기록 된 경우에도 여전히 잠금/트랜잭션 정보를 갖게됩니다. 귀하의 삭제가 따라옵니다, 블록을 읽고, 지금은 오래된 거래 정보를보고, 그것을 제거하고 블록을 다시 씁니다.

다섯 번째 가능성은 경합이다. 어쩌면 삭제와 동시에 더 많은 일이 일어 났을 것입니다.

가능성이 큽니다. 이를 재현 할 수 있으면 대기 이벤트를 사용하여 추적을 수행하고 TKPROF를 통해 실행하십시오.

관련 문제