2014-09-17 5 views
1

아마도 어리석은 질문이지만 다른 작업이 동일한 테이블을 업데이트 할 수 있도록 삽입을 분할/페이징하는 방법 일 수 있습니다.페이징 테이블에 대량 데이터 삽입

나는 두 개의 저장 프로 시저, 벌크 데이터

저장 프로 시저 InsertIntoMyTable 삽입 한했습니다 :

INSERT INTO MyTable (column1, Column2, Column3) 
SELECT Column1, @Column2, 0 
FROM MyOtherTable 
MyTable

기본 키가 (Column1, Column2)

입니다 또한 동일에 MERGE 수술을을 테이블 MyTable하지만 다른 소스에서 주로 업데이트 (column3) 또한 데이터를 MyTable에 삽입 할 수 있습니다.

MyTable에 삽입하는 데 많은 시간이 걸리므로 MERGE을 실행하는 저장 프로시 저는 InsertIntoMyTable이 완료 될 때까지 대기해야합니다. 이 문제를 해결하려고 할 때

는 작업이 끝날 때까지 테이블 잠금 여전히 매겨진

DECLARE @Start INT = 1 
DECLARE @End INT = 1000 
DECLARE @Amount INT = 1000 
DECLARE @Total INT 

SELECT @Total = COUNT(Column1) FROM MyOtherTable WHERE Column2 = @Column2 

WHILE (@Start<[email protected]) 
BEGIN 
    INSERT INTO MyTable (column1, Column2, Column3) 
     SELECT Column1, @Column2, 0 
     FROM (SELECT 
       Column1, 
       Row_number() OVER(ORDER BY Column1) rownumber 
      FROM MyOtherTable 
      WHERE Column2 = @Column2) x 
     WHERE x.rownumber between @start and @end 

    SET @start = @end+1 
    SET @End = @End + @Amount 
END 

하지만 추가.

참고 : 실행은 트랜잭션이 아닙니다.

답변

1

실행 는 트랜잭션에서입니다 - 당신이 명시 적 거래 자신을, SQL 서버는 암시 트랜잭션을 사용합니다 제공하지 않는 경우.

그리고 당신은 단일 트랜잭션에서 5000 개 이상의 작업 (INSERT, DELETE, UPDATE)가있는 경우, SQL Server는 개별 행 잠금을 삭제하고 대신 잠금 에스컬레이션을 대신 exlusively 잠 깁니다전체 테이블 - (암시적일 수도 있음) 트랜잭션이 커밋 (또는 롤백) 될 때까지는 다른 작업이 가능하지 않습니다.

1000 행의 블록에 삽입하는 부분은 잠금 에스컬레이션을 일으키지 않아야합니다. 물론 해당 트랜잭션의 컨텍스트에 삽입되는 행은 다른 트랜잭션에서 동시에 읽거나 조작 할 수 없습니다.

+1

고마워요! 매우 명확한 설명. 다시 한번 감사드립니다. –

+0

내 코드를 이와 같이 변경했습니다. WHILE (@start <= @ 총) 가 TRAN에게 여기 삽입을 BEGIN BEGIN ... 는 TRAN END 을 COMMIT하지만 여전히 삽입 될 때까지 모든 행을 차단합니다. –