2011-01-10 6 views
5

감안할 때 : SQL Server 2008 R2. 일부 speedin 데이터 디스크를 종료하십시오. 로그 디스크 지연.대용량 삽입 성능 최적화 ...?

필수 : ​​많은 양의 삽입이 필요합니다. 초당 두 개의 인덱스가있는 간단한 테이블에 10.000 ~ 30.000 행이 있습니다. 인서트는 본질적인 순서를 가지며 반복되지 않습니다. 이러한 인서트 순서는 단기간 내에 유지되어서는 안됩니다 (즉, 여러 개의 평행 인서트는 괜찮습니다).

지금까지 : 데이터를 대기열에 누적했습니다. 정기적으로 (비동기식 스레드 풀) 대기열에 들어오는 작업 항목에 최대 1024 개의 항목을 비 웁니다. 스레드 풀 (사용자 정의 클래스)에는 32 개의 가능한 스레드가 있습니다. 32 개의 연결을 엽니 다.

문제점 : 성능은 300 배로 떨어지고 .... 초당 약 100-150 행이 삽입됩니다. 로그 대기 시간은 SQL Server에서 최대 40 % - 처리 시간 (초당 ms)의 45 %입니다. 서버 CPU 부하가 적습니다 (4 % ~ 5 % 정도).

사용할 수 없음 : 대량 삽입. 데이터는 가능한 한 실시간으로 디스크에 기록되어야합니다. 이것은 시스템을 통해 실행되는 데이터의 아키비스트 프로세스이지만, 데이터에 정기적으로 액세스해야하는 쿼리가 있습니다. 나는 그들을 디스크에 버리고 일괄 업로드를 사용하여 초당 1-2 번 시도해 볼 수 있습니다.

누구나 스마트 아이디어? 다음 단계는 로그를 빠른 디스크 세트 (128GB 최신 ssd)로 옮기고 그 다음에 어떤 일이 발생하는지 확인하는 것입니다. 상당한 성능 향상은 아마도 상당히 다른 일을 할 것입니다. 그러나 그럼에도 불구하고 .... 문제는 실현 가능한지 여부입니다.

그래서 멋진 아이디어를 발사하십시오.

+3

에서 촬영? – Carth

답변

4

좋아, 아무쪼록. SqlBulkCopy에 65536 개의 항목을 일괄 처리하고 매 초마다 비동기식으로 플러시하려고 시도합니다. 이익에 대해보고합니다.

+3

3 스레드를 사용하여 초당 75.000 개의 레코드가 생성됩니다. – TomTom

+0

와우, 그거 꽤 인상적이고 멋진 작품이야! –

3

나는 정확히 같은 문제를 겪고 있기 때문에 성능 향상을 위해 수행 할 단계를 거치도록하겠습니다.

  • 별도의 로그와 다른 스핀들 세트 상에 DBF 파일
  • 를 사용하여 기본 복구
  • 당신이 삽입의 순서는 중요하지 않다는 사실 이외의 색인 요구 사항을 언급하지 않았다 -이에서를 식별 C 럼 이외의 다른 것에 대한 클러스터 된 인덱스는 사용하지 않아야합니다.
  • 동시성의 스케일링을 1에서 다시 시작하고 성능이 떨어지면 중지하십시오. 이것 이상의 어떤 것이라도 성능을 해칠 수 있습니다.
  • 디스크로 bcp로 이동하지 않고 SQL Server 2008을 사용할 때 한 번에 여러 행을 삽입하는 것이 좋습니다. 이 문은 단일 SQL 호출 테이블 값으로

    INSERT (1,2,3) (4,5,6)을, 나는 (7, 8, 9)

이었다 세 행을 삽입 단일 스레드에서 초당 ~ 500 개의 별개의 인서트로 토핑합니다. 네트워크와 CPU (클라이언트와 서버 모두에서 0)를 배제한 후, 서버의 디스크 io가 비난을 받았다고 가정했으나 3 회분을 삽입하면 초 당 1500 개의 삽입이 발생하여 디스크 io가 제외됩니다.

MS 클라이언트 라이브러리에는 상한값이 저장되어 있습니다 (반사경에 잠수하면 약간의 비동기 완료 코드가 표시됨).

삽입을 호출하기 전에 x 이벤트가 수신 될 때까지 대기하면서, 구성에 대한 상한선 인 단일 스레드에서 초당 2700 개의 삽입을 삽입합니다.

참고 : 항상 일정한 일정의 이벤트가 도착하지 않는 경우 특정 기간 후에 삽입을 플러시하는 타이머를 추가하는 것이 좋습니다 (따라서 마지막 날 일정을 볼 수 있습니다).

증가 삽입 성능을
1

제안 :

  • 증가 ADO.NET BatchSize에서
  • 삽입은 클러스터 된 인덱스 노드 분할로 이어질되지 않도록 현명하게 목표 테이블의 클러스터 된 인덱스를 선택합니다 (예 : 자동 증가 (Autoinc) 열)
  • 임시 힙 테이블에 먼저 삽입 한 다음 큰 "insert-by-select"문을 실행하여 모든 준비 테이블 데이터를 실제 대상 테이블에 밀어 넣습니다. "전체"복구 모델
  • 장소 (비즈니스 시나리오는 그것을 허용하는 경우) 삽입하기 전에 테이블 잠금을

혹시이에 최종 해결을 받으셨어요 Tips For Lightning-Fast Insert Performance On SqlServer