문제

당사의 앱은 SQL Server 2005 데이터베이스에 많은 양의 텍스트를 추가해야합니다 (단일 레코드의 경우 최대 1GB). 성능의 이유로, 이는 각 청크 (예 : USP_ADDCHUNK)에 대해 저장된 절차를 호출하여 청크에서 수행됩니다. USP_ADDCHUNK에는 명시적인 거래가 없습니다.

내가보고있는 것은 청크 크기를 100MB에서 10MB로 줄이면 훨씬 더 큰 트랜잭션 로그가 발생한다는 것입니다. USP_ADDCHUNK가 호출 될 때마다 "암시 적"(내 용어) 트랜잭션이 기존 텍스트를 모두 기록 할 수 있기 때문입니다. 150MB 레코드의 경우 :

100MB 청크 크기 : 100 (0 바이트 로그인) + 50 (100MB 로그인) = 100MB 로그인

보다 작을 것입니다

10MB 청크 크기 : 10 (0 바이트 로그인) + 10 (10MB 로그인) + 10 (20MB 로그인) ... + 10 (140MB 로그인) = 1050MB 로그인

C# 코드에서 트랜잭션을 열어서 (첫 번째 청크를 추가하고 마지막 청크 후 커밋하기 전에)이 "암시 적"트랜잭션은 발생하지 않을 것이라고 생각했으며 거대한 로그 파일을 피할 수 있다고 생각했습니다. 그러나 내 테스트에 따르면 ADO.NET 트랜잭션을 사용하여 트랜잭션 로그가 5 배 더 커집니다.

코드를 게시하지는 않지만 몇 가지 세부 사항이 있습니다.

  1. 나는 sqlconnection.begintransaction () 호출
  2. 나는 각 청크마다 다른 sqlcommand를 사용합니다
  3. (1)에서 각 sqlcommand에 sqltransaction을 할당합니다.
  4. 나는 일반적으로 각 sqlcommand 실행 후 연결을 닫지 만 동일한 결과와 연결을 닫지 않으려 고 노력했습니다.

이 계획의 결함은 무엇입니까? 더 많은 정보가 필요하면 알려주세요. 감사!

참고 : 간단하거나 벌크로드 복구 모델을 사용하는 것은 옵션이 아닙니다.

도움이 되었습니까?

해결책

'청크'에 의해 당신은 다음과 같은 것을 의미합니다.

UPDATE table
SET blob = blob + @chunk
WHERE key = @key;

그렇다면 작업이 완전히 기록 된 것이 맞습니다. 당신은 따라야합니다 Blob 사용 지침 chuncked 업데이트에 .write 메소드를 사용하십시오.

UPDATE table
SET blob.Write(@chunk, NULL, NULL)
WHERE key = @key;

이렇게하면 업데이트를 최소 로그인합니다 (가능하면 참조하십시오. 최소 로그인 할 수있는 작업):

업데이트 문이 완전히 기록됩니다. 그러나 .write 절을 사용하여 큰 값 데이터 유형에 대한 부분 업데이트가 최소 로그인됩니다.

이것은 최소 로그인 한 것뿐만 아니라 업데이트가 블로브 끝에 명시적인 쓰기이기 때문에 엔진은 블로브의 일부만 업데이트했으며 로그 만 기록한다는 것을 알게됩니다. 저것. 업데이트 할 때 SET blob=blob+@chunk TE Engine은 전체 블로브가 새로운 값을 받았으며 새로운 데이터를 추가하여 블로브 만 변경했다는 사실을 감지하지 않으므로 전체 블로브를 기록합니다 (이미 발견 한대로 여러 번). .

BTW 크기의 덩어리를 사용해야합니다.

최상의 성능을 위해서는 8040 바이트의 배수 인 청크 크기로 데이터를 삽입하거나 업데이트하는 것이 좋습니다.

다른 팁

당신이해야 할 일은 각 "청크"또는 덩어리 그룹을 자체 거래로 둘러싸고 각 그룹 후에 커밋하는 것입니다. 자신의 ADO 거래로 모든 것을 둘러싼 것은 본질적으로 암시 적 거래와 같은 일을하는 것이므로 도움이되지 않습니다. 로그를 더 작게 유지하려면 작은 덩어리로 커밋해야합니다.

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