programing

SQL에서 문 삭제가 매우 느립니다.

telecom 2023. 4. 20. 20:01
반응형

SQL에서 문 삭제가 매우 느립니다.

타임아웃을 앞둔 다음과 같은 진술이 있습니다.

DELETE FROM [table] WHERE [COL] IN ( '1', '2', '6', '12', '24', '7', '3', '5')

이렇게 한 번에 하나씩 해보려고 했는데

DELETE FROM [table] WHERE [COL] IN ( '1' )

아직까지는 22분인데 아직 진행 중입니다.

테이블에는 260,000개의 행이 있으며 4개의 열이 있습니다.

이게 왜 이렇게 느린지, 어떻게 하면 속도를 높일 수 있는지 아는 사람 있나요?WHERE를 실행하고 있는 [COL]에 특이하지 않은 비클러스터 인덱스가 있습니다.SQL Server 2008 R2를 사용하고 있습니다.

update: 테이블에 트리거가 없습니다.

삭제 속도가 느려질 수 있는 이유:

  • 많은 레코드 삭제
  • 많은 색인
  • 하위 테이블의 외부 키에 인덱스가 없습니다.(댓글에 이 점을 언급해 주신 @CesarAlvaradoDiaz님 감사합니다)
  • 교착 상태 및 차단
  • 트리거
  • cascade delete (삭제하는 10개의 부모 레코드는 수백만 개의 자녀 레코드가 삭제되는 것을 의미할 수 있습니다)
  • 확장해야 하는 트랜잭션 로그
  • 확인할 외부 키가 많습니다.

따라서 무엇이 차단되고 있는지 파악하여 수정하거나 정상 가동 부하를 방해하지 않는 오프타임에 삭제를 실행할 수 있습니다.삭제는 일괄적으로 실행할 수 있습니다(트리거, 캐스케이드 삭제 또는 다수의 레코드가 있는 경우에 편리합니다).인덱스를 삭제 및 재생성할 수 있습니다(비수기에도 재생성할 수 있는 것이 가장 좋습니다.

  1. 제약 조건을 무효로 하다

    ALTER TABLE [TableName] NOCHECK CONSTRAINT ALL;

  2. 인덱스 사용 안 함

    ALTER INDEX ALL ON [TableName] DISABLE;

  3. 인덱스 재구축

    ALTER INDEX ALL ON [TableName] REBUILD;

  4. 제약 조건을 유효하게 하다

    ALTER TABLE [TableName] CHECK CONSTRAINT ALL;

  5. 다시 삭제

많은 행을 삭제하는 것은 매우 느릴 수 있습니다.다음과 같이 한 번에 몇 개씩 삭제해 보십시오.

delete top (10) YourTable where col in ('1','2','3','4')
while @@rowcount > 0
    begin
    delete top (10) YourTable where col in ('1','2','3','4')
    end

제 경우 데이터베이스 통계가 손상되었습니다.스테이트먼트

delete from tablename where col1 = 'v1' 

일치하는 기록이 없는데 30초 걸렸는데

delete from tablename where col1 = 'rubbish'

즉석에서 달리다

입니다.

update statistics tablename

문제를 해결하다

삭제할 테이블에 BEFORE/AFTER DELETE 트리거가 있는 경우 지연의 원인이 될 수 있습니다.

또한 해당 테이블을 참조하는 외부 키가 있는 경우 추가 UPDATE 또는 DELETE가 발생할 수 있습니다.

예방 조치

의 도움을 받아 확인하다SQL Profiler를 참조해 주세요.Triggers실행이 지연되는 원인이 됩니다.네, 그렇습니다. 말고 Database Name ★★★★★★★★★★★★★★★★★」Object Name「 」를 기동하는 Trace

데이터베이스 이름 필터링

테이블/저장 프로시저/트리거 이름 필터링

수정 조치

26일, 26일, 26일, 26일, 26일, 26일, , 26일.IN Predicate6월 6일입니다.각 번 되고 있습니다.IN Predicate대신 아래처럼 이너조인이 되어야 하는데...

Delete K From YourTable1 K
Inner Join YourTable2 T on T.id = K.id

, 이렇게 '아까보다'를 넣으세요.IN Predicate에서 'a'로Temporary Table ★★★★★★★★★★★★★★★★★」Local Variable

다른 테이블에는 [테이블]에 대한 FK 제약이 있을 수 있습니다.따라서 DB는 참조 무결성을 유지하기 위해 이러한 테이블을 확인해야 합니다.이러한 FK에 대응하는 필요한 인덱스가 모두 있는 경우에도 해당 인덱스의 양을 확인하십시오.

NHIbernate가 중복된 FK를 같은 컬럼에 잘못 작성했지만 다른 이름(SQL Server에서 허용)으로 작성한 적이 있습니다.DELETE 스테이트먼트의 실행이 큰폭으로 늦어지고 있습니다.

이 삭제문의 실행계획을 확인하십시오.인덱스 시크가 사용되고 있는지 확인합니다.또한 col의 데이터 유형은 무엇입니까?

잘못된 데이터 유형을 사용하는 경우 업데이트 문을 '1'에서 '1' 또는 'N'1'로 변경합니다.

인덱스 검색을 사용하는 경우 몇 가지 쿼리 힌트 사용을 고려하십시오.

선택한 레코드가 아닌 테이블 내의 모든 레코드를 삭제할 경우 테이블을 드롭하고 다시 작성하는 것이 훨씬 빠를 수 있습니다.

[COL]은 정말로 숫자를 유지하는 문자 필드입니까, 아니면 값 주위에 있는 단일 따옴표를 제거할 수 있습니까?@Alex는 IN이 =보다 느리므로, 이 작업을 수행할 수 있다면 더 잘 살 수 있을 것입니다.

DELETE FROM [table] WHERE [COL] = '1'

그러나 행을 찾기 위해 문자열이 아닌 숫자를 사용하는 것이 더 좋습니다(sql은 숫자를 좋아합니다).

 DELETE FROM [table] WHERE [COL] = 1

시도해 보세요.

 DELETE FROM [table] WHERE CAST([COL] AS INT) = 1

두 경우 모두 테이블 스캔 속도를 높이기 위해 [COL] 열에 인덱스가 있는지 확인하십시오.

나는 이 기사를 읽었는데, 그것은 어떤 불편함도 해결하는데 큰 도움이 되었다.

https://support.microsoft.com/en-us/kb/224453

이것은 waitresource KEY의 경우: 16:72057595075231744(ab74b4daaf17)

-- First SQL Provider to find the SPID (Session ID)

-- Second Identify problem, check Status, Open_tran, Lastwaittype, waittype, and waittime
-- iMPORTANT Waitresource select * from sys.sysprocesses where spid = 57

select * from sys.databases where database_id=16

-- with Waitresource check this to obtain object id 
select * from sys.partitions where hobt_id=72057595075231744

select * from sys.objects where object_id=2105058535

SSIS 패키지(명령어를 매우 느리게 실행하는 SQL Server로 인해)를 검사한 결과, 이 글을 쓰기 약 5~4년 전에 클라이언트에 셋업된 다음 작업이 있음을 알게 되었습니다. 1) XML 파일의 데이터를 [Importbarcdes]라는 테이블에 삽입하십시오.

2) 위의 표를 소스로 사용하여 다른 타깃테이블에서 merge 명령어를 발행합니다.

3) "[Import Barcodes]에서 삭제" - SSIS 패키지의 태스크에서 XML 파일을 읽은 후 삽입된 행을 지웁니다.

간단한 검사 후 1줄밖에 없는 ImportBarcodes 테이블 상의 모든 문(SELECT, UPDATE, DELETE 등)을 실행하는 데 약 2분이 소요되었습니다.

확장 이벤트에 PAGEIOLACH_EX 대기 알림이 많이 표시되었습니다.

테이블에 인덱스가 없고 트리거가 등록되지 않았습니다.

테이블의 속성을 자세히 검사한 결과 Storage 탭과 General 섹션의 Data Space 필드에 6 GIGAB가 넘게 표시되었습니다.페이지에 할당된 공간의 YTES입니다.

무슨 일이 일어났는지:

쿼리는 지난 4년간 매일 상당 시간 실행되어 테이블 내의 데이터를 삽입 및 삭제하고 사용하지 않는 페이지 파일을 남겨두었습니다.

이것이 Extended Events Session에 의해 캡처된 대기 이벤트와 테이블에서 실행되는 명령어의 주된 이유입니다.

입니다.ALTER TABLE ImportBarcodes REBUILD문제를 수정하여 사용되지 않는 공간을 모두 확보했습니다. TRUNCATE TABLE ImportBarcodes모든 페이지 파일과 데이터를 삭제한다는 차이만 있을 뿐, 비슷한 작업을 수행했습니다.

오래된 주제지만 여전히 관련이 있는 주제입니다.또 다른 문제는 인덱스가 도움말보다 문제가 될 정도로 단편화되었을 때 발생합니다.이 경우 인덱스를 재구축하거나 삭제하고 다시 작성한 후 삭제문을 다시 발행하면 됩니다.

Andomar의 답변의 연장선상에서, 저는 첫 번째 7억 개의 레코드(약 12억 개)가 초당 25,000 개의 레코드 청크로 매우 빠르게 처리되는 시나리오를 가지고 있었습니다.그런데 25,000개를 하는 데 15분이 걸리더라고요.청크기를 5,000레코드로 줄였고 이전 속도로 돌아갔습니다.내부 임계값이 어느 정도인지는 모르겠지만, 기록을 더 줄이고 속도를 되찾는 것이 해결책이었다.

CMD를 열고 이 명령을 실행합니다.

NET STOP MSSQLSERVER
NET START MSSQLSERVER

SQL Server 인스턴스가 재시작됩니다.삭제 명령 후 재실행 시도

이 명령어는 배치 스크립트에 포함되어 있으며 이와 같은 문제가 발생할 경우 수시로 실행합니다.일반적인 PC 재부팅은 동일하지 않으므로 SQL 서버에서 문제가 발생한 경우 인스턴스를 재시작하는 것이 가장 효과적인 방법입니다.

언급URL : https://stackoverflow.com/questions/10901299/delete-statement-in-sql-is-very-slow

반응형