문제

SQL Enterprise Manager 2000에서 작업을 구성하여 몇 개의 데이터베이스 테이블에서 레코드를 복사하고 삭제하고 있습니다. 우리는 직선적 인 질량 사본을 실행하고 저장된 절차를 삭제했지만 수백만 행으로 실행할 수 있으므로 서버를 걸 수 있습니다. 한 번에 100-ish 레코드 청크에서 서비스를 실행하는 데 관심이 있었기 때문에 서버는 중단되지 않습니다 (이것은 라이브 웹 데이터베이스입니다). 이 서비스가 밤에 한 번 운영되기를 원하기 때문에 에이전트 작업에 넣었습니다. 실제로 사본을 수행하고 삭제하는 저장된 절차로 통화를 반복 한 다음 각 호출 사이에 "수면"을 통해 서버가 따라 잡을 시간을 줄 수있는 방법이 있습니까? Waitfor 명령이 있다는 것을 알고 있지만 이것이 프로세서를 보유하거나 그 동안 다른 쿼리를 실행하게할지 확실하지 않습니다.

감사!

도움이 되었습니까?

해결책

"Chunkify"는 삭제가 트랜잭션 로그 파일을 팽팽하게하지 않고 과도한 양의 데이터를 삭제하는 선호하는 방법입니다. Bradc의 게시물은 이것의 합리적인 예입니다.

이러한 루프 관리는 단일 저장 절차 내에서 가장 잘 수행됩니다. 시간이 지남에 따라 그러한 운동을 전파하기 위해서도 여전히 절차에 보관합니다. 루프에 대기 시간을 삽입하면 가능한 동시성 문제를 다루는 데 필요한 것으로 간주되는 경우 각 삭제 세트 사이에 "일시 중지"가 표시됩니다. SQL 에이전트 작업을 사용하여 절차가 시작되는시기를 결정하고 특정 시간까지 중지 해야하는 경우 루프에도 적용하십시오.

이 코드에 대한 나의 스핀은 다음과 같습니다.

--  NOTE: This is a code sample, I have not tested it
CREATE PROCEDURE ArchiveData

    @StopBy DateTime
    --  Pass in a cutoff time.  If it runs this long, the procedure will stop.
AS

DECLARE @LastBatch  int

SET @LastBatch = 1
--  Initialized to make sure the loop runs at least once


WHILE @LastBatch > 0
 BEGIN

    WAITFOR DELAY '00:00:02'
    --  Set this to your desired delay factor

    DELETE top 1000  --  Or however many per pass are desired
     from SourceTable
    --  Be sure to add a where clause if you don't want to delete everything!

    SET @LastBatch = @@rowcount

    IF getdate() > @StopBy
        SET @LastBatch = 0

 END

RETURN 0

흠. 게시물을 다시 읽으면 데이터를 삭제하기 전에 먼저 어딘가에 데이터를 복사하려고합니다. 이를 위해 온도 테이블을 설정하고 루프 내부에 먼저 온도 테이블을 자른 다음 상단 N 항목의 기본 키에 복사 한 다음 온도 테이블에 조인을 통해 "아카이브"테이블에 삽입하십시오. 그런 다음 온도 테이블에 조인을 통해 소스 테이블을 삭제하십시오. (직선 삭제보다 조금 더 복잡하지 않습니까?)

다른 팁

루프 간 대기에 대해 걱정하지 마십시오. SQL Server는 유지 보수 작업과 서버의 정기 활동 간의 경합을 처리해야합니다.

이러한 유형의 상황에서 실제로 문제를 일으키는 것은 전체 삭제 프로세스가 단일 트랜잭션 내에서 한 번에 발생한다는 것입니다. 이것은 데이터베이스의 로그를 날려 버리고, 당신이 겪고있는 것처럼 들리는 종류의 문제를 일으킬 수 있습니다.

이와 같은 루프를 사용하여 관리 가능한 청크를 삭제하십시오.

DECLARE @i INT
SET @i = 1

SET ROWCOUNT 10000

WHILE @i > 0
BEGIN
    BEGIN TRAN
        DELETE TOP 1000 FROM dbo.SuperBigTable
        WHERE RowDate < '2009-01-01'
    COMMIT

    SELECT @i = @@ROWCOUNT
END
SET ROWCOUNT 0

사본에 유사한 논리를 사용할 수 있습니다.

WAITFOR 다른 프로세스가 '이동'하게 할 것입니다. 이 기술을 사용하여 Barge Delete의 기계 잠금을 중지했습니다. while 루프를 만들고 행 블록을 삭제 한 다음 몇 초 동안 대기하십시오 (또는 적절한 것이 적음).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top