.NET 코드에서 SQL Server 테이블에 삽입하는 가장 빠른 방법은 무엇입니까?

sqlbulkcopy sql-server-2008

문제

이렇게하는 가장 빠른 방법은 무엇입니까?

  • 하나의 테이블, 내가 미리 채울 수없는 참조가 없습니다 (즉, 여기에 하나의 참조 키가 있지만 모든 데이터가 채워져 있습니다)
  • 많은 데이터. 우리는 하루에 수억 개의 행을 말하며 API를 통해 동적으로 들어옵니다.
  • 요청은 거의 실시간 시나리오에서 가능한 빨리 처리해야합니다 (즉, 하루에 업로드 할 파일에 쓰지 않아야 함). 정상적인 최대 지연은 2 초입니다.
  • 데이터 / 응용 프로그램 및 SQL Server를위한 별도의 시스템

지금 내가 뭘하는지 :

  • 최대 32 * 1024 행을 배열에 집계 한 다음 대기열에 넣습니다.
  • 2-3 개의 스레드로 큐를 읽습니다. SqlBulkCopy를 사용하여 데이터베이스에 삽입하십시오.

초당 약 60k-75k 행을 가져 오는데 충분하지는 않지만 아주 가깝습니다. 나는 250.000 행을 치고 싶다.

지금까지 아무 것도 실제로 사용되지 않습니다. 나는 20 % 시간 "네트워크 I / O"블록을 가지며, 하나의 코어 80 %가 CPU 측면에로드되어있다. 디스크는 주로 유휴 상태 인 7MB ~ 14MB로 쓰고 있습니다. 6 랩터의 RAID 10에 대한 평균 대기열 길이는 .... 0.25입니다.

누구든지이 속도를내는 방법을 알고 있습니까? 더 빠른 서버 (지금까지는 가상, 8GB 램, 4 코어, 물리적 디스크 통과).


몇 가지 설명 추가 :

  • 이것은 2008 R2 서버의 2008 R2 Enterprise SQL Server입니다. 기계에는 4 개의 코어, 8GB RAM이 있습니다. 모두 64 비트. 80 % 부하 평균은이 기계에서 약 20 %의 CPU 부하를 보여줍니다.
  • 테이블은 단순하고, 기본 키가없고, 관계형 참조 (계기 참조)에 대한 색인과 고유 (계측기 세트 내에서 이것은 시행되지 않음) 타임 스탬프입니다.
  • 테이블의 필드는 타임 스탬프, 악기 참조 (시행 된 외래 키 없음), 데이터 유형 (char 1, 게시되는 데이터를 나타내는 문자 수 중 하나), 가격 (double) 및 볼륨 (int)입니다. 보시다시피 이것은 매우 얇은 테이블입니다. 해당 데이터는 금융 상품에 대한 틱 데이터입니다.
  • 질문은 하드웨어에 대해서도 마찬가지입니다. 대부분 병목 현상이 보이지 않기 때문입니다. 나는 여러 거래에 삽입하고 있는데 그것은 나에게 유익을 주지만 작은 하나이다. 디스크, CPU는 상당한 부하를 보이지 않으며 네트워크 대기 시간은 높습니다 (현재 300ms / 초, 30 %).하지만 이는 두 서버를 JSUT로 실행하는 동일한 가상화 플랫폼에 있으며 모두를 실행하기에 충분한 코어가 있습니다. 나는 "다른 서버를 사다"라는 말을 꽤 많이하지만, 병목을 먼저 확인하고 싶습니다. 특히 하루가 끝날 때 병목 현상을 파악하지는 못했습니다. 로깅은 부적합합니다. 대량 삽입은 데이터 (클러스터 된 색인 없음)로 데이터 로그에 저장되지 않습니다.

수직 파티셔닝이 도움이 될까요? 예를 들어 바이트 (tinyint)가 계기를 16 개의 테이블로 나눠서 나눠서 16 개의 삽입을 동시에 할 수 있습니까? 실제로 데이터는 다른 교환기에서 가져온 것이므로 교환 당 파티션을 만들 수 있습니다. 이것은 자연 스플릿 필드 (실제로 악기에 있지만이 데이터를 여기에 복사 할 수 있음)입니다.


몇 가지 더 명확한 설명 : 속도가 훨씬 빨라짐 (90k). 이제는 VM 스위치가 될 수있는 머신 간의 네트워크 IO에 의해 분명히 제한됩니다.

지금 내가하는 일은 32K 행당 연결을 수행하고 임시 테이블을 올리며 SqlBUlkdCopy로 삽입 한 다음 하나의 SQL 문을 사용하여 주 테이블에 복사합니다. 주 테이블에서 모든 잠금 시간을 최소화합니다.

대부분의 대기 시간은 네트워크 IO에 있습니다. VM이 현명한 경우 문제가 발생하는 것 같습니다. 다음 달에는 물리적 하드웨어로 이동합니다.)

인기 답변

초당 70k 행을 관리하는 경우 지금까지 매우 운이 좋았습니다. 그러나 당신이 아주 간단한 스키마를 가지고 있기 때문에 그것이 의심 스럽습니다.

이런 종류의 부하에 대해 물어볼 수는 없습니다.

  • 가상 서버
  • 단일 배열
  • SATA 디스크

네트워크와 CPU는 공유되며 IO는 제한되어 있으므로 모든 리소스를 사용할 수는 없습니다. 표시되는로드 통계는 그다지 유용하지 않습니다. 네트워크 부하가 2 개의 가상 서버 사이의 트래픽이라고 생각합니다.이 문제를 해결하면 IO 경계가됩니다.

계속하기 전에 35K tps 에서이 10 가지 강의를 읽으십시오. 그는 가상 박스를 사용하지 않았습니다.

볼륨을 높이려면 SAN과 DR 기능이 없다고 가정하면됩니다.

  • 2 개의 큰 phyical 서버, CPU RAM 종류의 irreleveant, 최대 RAM 구매 x64 설치
  • 디스크 + 컨트롤러 = 가장 빠른 스핀들, 가장 빠른 SCSI. 또는 훌륭한 NAS
  • 1000MB + NIC
  • 데이터베이스의 로그 파일 에만 6-10 개의 디스크가있는 RAID 10
  • 데이터 파일 용 디스크 RAID 5 또는 RAID 10 남음

참고로 피크로드는 시간당 1200 만 행 (16 코어, 16GB, SAN, x64)이지만로드가 복잡합니다. 우리는 능력이 없습니다.



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.