SqlBulkCopy에 권장되는 배치 크기는 얼마입니까?


답변:


97

SQL Server 인스턴스와 동일한 물리적 서버에 가져 오기 유틸리티가 있습니다. 사용자 정의를 사용하여 IDataReader플랫 파일을 구문 분석하고을 사용하여 데이터베이스에 삽입합니다 SQLBulkCopy. 일반적인 파일에는 약 6M의 규정 된 행이 있으며, 10 진수 및 짧은 텍스트의 평균 5 개 열 (행당 약 30 바이트)이 있습니다.

이 시나리오를 감안할 때 배치 크기가 5,000이라는 것이 속도와 메모리 소비의 가장 좋은 절충안이라는 것을 알았습니다. 나는 500으로 시작하여 더 큰 것으로 실험했습니다. 5000은 평균적으로 500보다 2.5 배 빠르다는 것을 알았습니다. 6 백만 개의 행을 삽입하는 데는 배치 크기가 5,000 인 경우 약 30 초, 배치 크기가 500 인 경우 약 80 초가 걸립니다.

10,000은 눈에 띄게 빠르지 않았습니다. 최대 50,000 개로 이동하면 속도가 몇 퍼센트 포인트 향상되었지만 서버의 부하가 증가 할 가치는 없습니다. 50,000 이상에서는 속도가 향상되지 않았습니다.

이것은 공식이 아니지만 사용할 수있는 또 다른 데이터 포인트입니다.


3
고려해야 할 한 가지는 테이블이 비어 있고 인덱스가있는 경우입니다. 이러한 경우 여기에 언급 된대로 하나의 배치로 모든 것을 업로드 할 수 있습니다. technet.microsoft.com/en-us/library/ms177445(v=sql.105).aspx "인덱스가있는 빈 테이블로 데이터를 대량으로 가져 오는 경우 배치 크기를 지정하면 첫 번째 배치 후에 테이블이 비어 있지 않습니다. 두 번째 배치부터는 데이터가 완전히 기록됩니다. 색인이 생성 된 빈 테이블의 경우 단일 배치로 대량 가져 오기를 수행하는 것이 좋습니다. "
— Sal

SqlBulkCopy는 소스 (예 : DataTable)에서 Sql로 데이터를 스트리밍하므로 큰 배치 크기에서 "서버의 증가 된로드"가 무엇입니까? (예 : 50,000)
— BornToCode

29

이것은 내가 또한 시간을 들여 조사한 문제입니다. C # 콘솔 응용 프로그램 (.Net 2.0)을 사용하여 큰 CSV 파일 (16GB 이상, 6 천 5 백만 개 이상의 레코드 및 증가하는 레코드)을 SQL Server 2005 데이터베이스로 가져 오는 것을 최적화하려고합니다. 으로 제레미가 있다 이미 지적 , 당신은 당신의 특정한 상황에 대한 몇 가지 미세 조정을 수행해야합니다,하지만 난 당신이 500의 초기 배치의 크기가 추천, 테스트는 이상이 아래에 모두 값.

이 MSDN 포럼 게시물 에서 배치 크기에 대해 100에서 1000 사이의 값을 테스트하라는 권장 사항을 받았으며 회의적이었습니다. 그러나 100에서 10,000 사이의 배치 크기를 테스트했을 때 500이 내 애플리케이션에 가장 적합한 값이라는 것을 알았습니다. 500 값 SqlBulkCopy.BatchSize도 여기에서 권장 됩니다 .

SqlBulkCopy 작업을 더욱 최적화하려면이 MSDN 조언을 확인하십시오 . SqlBulkCopyOptions.TableLock을 사용하면로드 시간을 줄이는 데 도움이됩니다.


서버 자체에서 대량 복사 명령을 실행하는 것이 아마도 더 빠를 것이라고 생각합니다.
— 캡틴 Kenpachi

16

다른 사람들이 말했듯이, 이는 사용자 환경, 특히 행 볼륨 및 네트워크 대기 시간에 따라 다릅니다.

개인적으로 BatchSize속성을 1000 행 으로 설정하고 그 성능을 확인합니다. 작동하면 시간 초과가 발생할 때까지 행 수를 계속 두 배로 늘립니다 (예 : 2000, 4000 등).

그렇지 않고 시간 초과가 1000에서 발생하면 작동 할 때까지 행 수를 절반 (예 : 500)으로 줄입니다.

각각의 경우에, 나는 배 (성공하면) 또는 (실패한 경우) 절반으로 유지 차이를 마지막으로 시도한 두 배치 크기 를 스위트 스팟을 찾을 때까지 .

고려해야 할 다른 요소는 단일 일괄 처리 행 을 복사하는 데 걸리는 시간 입니다. 복사중인 행의 일괄 처리 BulkCopyTimeout가 기본적으로 30 초인 속성을 초과하면 시간 초과가 발생합니다 . BulkCopyTimeout속성을 60 초로 두 배로 늘릴 수 있습니다 . 이렇게하면 더 많은 배치 행 세트를 복사 할 수있는 더 긴 시간이 허용됩니다. 예를 들어, 50,000 개 행의 일괄 처리는 30 초 제한 시간을 초과하여 약 40 초가 소요될 수 있으므로 최대 60 초까지 범프하면 성능에 도움이 될 수 있습니다.


4

이것은 모두 구현에 달려 있습니다.

네트워크에서 어떤 종류의 속도를 기대할 수 있습니까? Forms 또는 ASP.Net에서 사용하고 있습니까? 사용자에게 진행 상황을 알려야합니까? 전체 작업의 규모는 얼마입니까?

내 경험상 배치 크기를 지정하지 않고 대량 복사를 실행하면 시간 초과 문제가 발생합니다. 저는 1000 개의 레코드로 시작하여 거기에서 약간의 조정을하고 싶습니다.


속도 : 다양 함, WebForms : 예, ASP.NET : 예, 와이드 테이블 : 예, 좁은 테이블, 예. 수천 개의 행 : 예. 수백만 행 : 예. 시나리오를 생각할 수 있다면 아마 그렇게하고있을 것입니다.
— Jonathan Allen

1
나는 그때 나의 이전 대답을 고수해야한다. 은색 총알이 없다고 생각합니다.
— Jeremy

-1

나는 여러 크기를 시도했지만 내 경우에는 5000이 좋았습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.