2009-08-25 5 views
23

나는오라클 쿼리 삭제에 너무 많은 시간이 걸림

DELETE from tablename where colname = value; 

과 같은 쿼리를 실행하는데 오래 걸립니다. 이유는 무엇입니까? colname에 대한 색인이 있습니다.

+0

쿼리의 Explain 계획을 게시 할 수 있습니까 (SQL * Plus에서 "SET AUTOTRACE ON EXPLAIN"을 실행 한 후 쿼리를 실행하십시오)? –

+0

SQL> 설명에 autotrace 설정 SQL> tablename에서 삭제 nid = 1250626; 행 1 개가 삭제되었습니다. 실행 계획 ------------------------------------------------ ---------- 0 DELETE STATEMENT Optimizer = ALL_ROWS (비용 = 2 카드 = 1 바이트 = 48) 1 0 '테이블 이름'삭제 2 1 'PK_tablename'의 INDEX (UNIQUE SCAN) (INDEX (UNIQUE)) (비용 = 1 카드 = 1 바이트 = 48) 이것은 1 행을 삭제하기위한 것입니다. 원래 검색어에는 '> ='조건이 있는데, 약 20 분이 지나면 완료를 볼 수 없습니다. '='을 사용해도 1 분 이상 걸립니다. – Ajay

+0

* SELECT * FROM tablename where nid = 1250626; *의 성능은 어떻습니까? – Christian13467

답변

30

쿼리 시간이 오래 걸리는 이유에 대한 여러 가지 설명이있을 수 있습니다 : 다른 세션 (대부분)에 의해 차단 될 수

  1. . 문제 SELECT NULL FROM tablename WHERE colname=:value FOR UPDATE NOWAIT
  2. 이 테이블을 가리키는 UNINDEXED REFERENCE CONSTRAINTS에 대한 확인이 (도움이 될 것입니다 script from AskTom가 추가 작업을하는 ON DELETE TRIGGER을,있을 수 있습니다 : 당신은 당신이 다른 있는지 아무도는 예를 들어, 행을 잠그고해야 삭제하기 전에 그러한 색인화되지 않은 외래 키가 있는지 여부를 결정합니다.
+0

이었지만 옵션 1과 2는 아니 었습니다. – Ajay

+2

3 번째는 infact 솔루션입니다 :). 이제 2 초 이내에 실행됩니다! – Ajay

+0

도움이 된 것을 기쁘게 생각합니다. 사실 내가 간과 할 가능성이 가장 높기 때문에 아마 1 위 자리에 세 번째 지점을 넣어야합니다. –

4

테이블이 여러 테이블과 관련되어있을 수 있습니다. 행 수가 많습니다.

+0

옙에 의해 언급했다. 옳은! 이것은 대답을위한 거대한 부모 테이블 – Ajay

2

해당 색인은 선택 사항입니까? 테이블에 백만 개의 행이 있고이 값이 1 만 5 천 개에 도달하면 색인이 쓸모가 없습니다. 사실 실제로 사용된다면 쓸모없는 것보다 더 나쁠 수도 있습니다. DELETE는 SELECT 문과 비슷하다. 액세스 경로를 조정할 수있다.

또한 삭제는 많은 실행 취소 테이블 공간을 차지하므로 시스템 사용량이 많은 경우 삭제가 발생할 수 있습니다. 다중 사용자 시스템에서 다른 세션은 삭제하려는 행을 잠글 수 있습니다.

ON DELETE 트리거가 있습니까? ON DELETE CASCADE 외래 키 제약 조건이 있습니까?

편집 :은 당신이 말하는 모든 것을 감안할 때, 그리고 문제, 특히 열은 당신이 훨씬 더 가능성이 시간이 오래 걸릴 경우, 하나의 행을 삭제하려고하므로 기본 키있는 그 어떤 다른 프로세스 또는 사용자가 행에 잠금을가집니다. V$LOCK에 아무것도 표시됩니까?

+0

삭제할 때 트리거가 없습니다. 표에 100 만 개가 넘는 행이 있습니다. 인덱싱 된 열이 기본 키입니다. ON DELETE CASCADE 제약 조건은 없습니다. 행을 삭제하는 데 약 1 초가 걸리는> 1 백만 행 이상의 또 다른 상위 테이블이 있습니다! – Ajay

0

테이블에 더 많은 레코드가 저장되어 있습니까?
데이터베이스 서버에서 실행되는 재귀 프로그램 (일부 중첩 루프 등)이 있습니까?
데이터베이스 서버가 다른 컴퓨터에있는 경우 네트워크 문제를 확인하십시오.

+0

서버쪽에 재귀 pgms이 없습니다. n/w problm 없음 – Ajay

0

그래서 난 그냥 내 경험을 게시 할 수 있습니다. 누군가에게 도움이 될 수 있습니다.

delete from foo 
where foo_id not in ( 
    select max(foo_id) from foo group by foo_bar_id, foo_qux_id 
); 

쿼리는 16 초를했다. 테이블 foo에 총 2300 개의 레코드 중 1700 개의 레코드가 삭제되었습니다.

외래 키의 모든 색인을 다른 답변에서 지시 한대로 검사했습니다. 그건 도움이되지 않았어.

솔루션 :

내가 innot in을 변경 한

delete from foo 
where foo_id in ( 
    select foo_id from foo 
    minus 
    select max(foo_id) from foo group by foo_bar_id, foo_qux_id 
); 

에 쿼리를 변경하고 정확한 결과를 얻기 위해 minus을 사용했다.

이제 쿼리는 0.04 초 후에 실행됩니다.

관련 문제