2011-12-08 2 views
0

약 550 만 레코드가있는 테이블이 있습니다. 날짜를 기준으로 일부 레코드를 삭제해야합니다. 내 쿼리는 다음과 같습니다.삭제 오랜 시간이 걸립니다

DELETE FROM Table WHERE [Date] between '2011-10-31 04:30:23' and '2011-11-01 04:30:42' 

약 9000 행이지만이 작업은 매우 오랜 시간 지속됩니다. 어떻게 속도를 높일 수 있습니까? 날짜는 datetime2의 유형이며, 테이블에는 int 기본 키가 있습니다. 업데이트 및 삭제 트리거는 사용할 수 없습니다.

+2

'[날짜]'에 대한 색인이 있습니까? –

+0

열 이름을 날짜가 아닌 다른 것으로 변경하십시오. ** 예약어와 같은 열 이름을 사용하는 것은 결코 좋은 생각이 아닙니다. 당신은 어떤 시점에서 고통의 세계로 끝날 것입니다. 게으르다. 그것은 날짜가 아니며, 창조 된 날짜 또는 게시 된 날짜 또는 그와 같은 것입니다. 적절하게 이름을 지정하십시오. – Cruachan

답변

2

[날짜]가 모든 행의 문자열로 변환되어 전체 테이블을 순차적으로 검색 할 가능성이 있습니다.

대신 날짜에 매개 변수를 캐스팅하려고한다 :

DELETE FROM Table WHERE [Date] between convert(datetime, '2011-10-31 04:30:23') and convert(datetime, '2011-11-01 04:30:42') 

는 또한, 첫째로 당신이 날짜에 인덱스를 가지고 있는지 확인 [Date]

+0

정말 도움이 된 색인을 작성해 주셔서 감사합니다. – viki

+0

시스템에 다른 사용자가없는 경우 "with (holdlock)"가 도움이 될 수 있습니다. – Paparazzi

1

에 인덱스가 거기에 있는지 확인하십시오.

인덱스가있는 경우 실행 계획을 확인하고 사용 중인지 확인하십시오. 인덱스를 사용하는 것이 삭제를 처리하는 가장 효율적인 방법이라는 것을 항상 따르지는 않습니다 (엄지 규칙이 10 %를 초과하는 경우) 인덱스 룩업 테이블의 추가 오버 헤드가 up은 전체 스캔보다 클 수 있습니다.

큰 테이블의 경우 데이터베이스가 테이블의 행 수를 잘못 이해하면 실행 계획에서 부적절한 선택을하게되므로 통계가 최신 상태인지 확인하는 것이 좋습니다 (실행 sp_updatestats). . 예를 들어, 통계가 정확하지 않은 경우 데이터베이스는 존재하는 경우에도 표보다 훨씬 적은 수의 레코드가 있다고 생각하기 때문에 색인을 무시하기로 결정할 수 있습니다. 날짜의 이상한 분포는 비슷한 효과를 가질 수 있습니다.

나는 인덱스를 삭제 한 다음 다시 작성하려고합니다. 인덱스는 이진 트리이며 효율적으로 작동하려면 균형을 이루어야합니다. 데이터가 시간이 지남에 따라 누적되면 인덱스가 일방적으로 부 풀릴 수 있으며 쿼리가 적절한 데이터를 찾는 데 오랜 시간이 걸릴 수 있습니다. 이 문제와 통계 문제는 데이터베이스 유지 관리 작업에 의해 자동으로 처리되어야하지만 간과되는 경우가 많습니다.

마지막으로 테이블에 다른 많은 인덱스가 있는지 말하지 않습니다. 그렇다면 인덱스를 다시 작성하고 인덱스를 업데이트 할 때 인덱스를 재구성해야하는 데이터베이스 문제가있을 수 있습니다. 약간은 과감하지만 삭제를 실행하기 전에 테이블에 다른 모든 인덱스를 삭제 한 다음 나중에 다시 만듭니다.

+2

좋은 답변입니다. 언급하지 않은 것은 외래 키 제약 조건입니다. 자식 데이터가 이미 삭제되었다는 것을 알고 있다고 생각하더라도 확인을 받아야합니다. 이렇게하면 삭제 속도가 크게 저하 될 수 있습니다. 때로는 FK가 많은 경우 작은 배치로 삭제해야합니다. – HLGEM

+0

감사합니다. [날짜]에 새 색인을 작성 했으므로 작업 속도가 빨라졌습니다. [날짜]에 관련된 쿼리가 없었기 때문에 [날짜]에 이전에 인덱스가 없었습니다 (PK에 클러스터 된 인덱스 만있었습니다). 또한 추가 정보를 주셔서 감사합니다, 그것은 매우 유용합니다. – viki

+0

@HGLEM. 좋은 지적이야, 잊어 버렸어. – Cruachan

관련 문제