많은 수의 행을 삽입하는 가장 빠른 방법은 무엇입니까?


27

나는이 준비 테이블에서 파일을 준비 테이블에로드하는 데이터베이스가 있는데, 외래 키를 해결하기 위해 1-2 조인이 있고이 행을 최종 테이블에 삽입합니다 (한 달에 파티션이 있음). 3 개월 동안 약 34 억 개의 행이 있습니다.

이러한 행을 최종 테이블로 스테이징하는 가장 빠른 방법은 무엇입니까? SSIS 데이터 흐름 태스크 (보기를 소스로 사용하고 빠른로드 활성화 됨) 또는 Insert INTO SELECT .... 명령? Data Flow Task를 시도했는데 약 5 시간 (서버의 8 코어 / 192GB RAM)으로 약 10 억 행을 얻을 수있어 매우 느립니다.


1
파티션이 별도의 파일 그룹에 있습니까 (그리고 다른 물리 디스크에있는 파일 그룹에 있습니까)?
Aaron Bertrand

3
정말 좋은 자료 Data Loading Performance Guide . 이것은 TF610 활성화 , BCP OUT / IN, SSIS 사용 등과 같이 수행 할 수있는 많은 성능 최적화를 해결합니다 . 권장 사항을 따르고 환경에서 테스트하면됩니다.
Kin Shah

@Aaron 그렇습니다. 한 달에 하나의 파일 그룹, 12 개의 san lun이 첨부되어 모든 jan이 하나의 lun 등으로 이동합니다. lun 당 디스크 수는 확실하지 않지만 충분해야합니다.
nojetlag

그래, 난 정말 "디스크 세트"를 의미했고 아마도 컨트롤러를 언급했을 수도 있습니다.
Aaron Bertrand

@Kin은 가이드를 보았지만 구식 인 것 같습니다. "SQL Server 대상은 Integration Services 데이터 흐름에서 SQL Server로 데이터를 대량로드하는 가장 빠른 방법입니다.이 대상은 ROWS_PER_BATCH를 제외한 SQL Server의 모든 대량로드 옵션을 지원합니다. " SSIS 2012에서는 성능 향상을 위해 OLE DB 대상을 권장합니다.
nojetlag

답변:


25

한 가지 일반적인 접근법 :

  1. 대상 테이블에서 인덱스 / 제약을 비활성화 / 삭제합니다.
  2. INSERT dbo.[Target] WITH (TABLOCKX) SELECT ...
  3. 물론 JNK에 대한 크레딧으로 위의 n행 을 일괄 처리 하여 트랜잭션 로그의 부담을 줄일 수 있으며 일부 배치가 실패하면 해당 배치에서 시작하면됩니다. 나는 이것에 대해 블로그를 작성했다 (삭제와 관련하여 동일한 기본 개념이 적용됨) : http://www.sqlperformance.com/2013/03/io-subsystem/chunk-deletes
  4. 대상 테이블에서 인덱스 / 제약을 다시 활성화 / 재 작성합니다 (모든 작업에 필요하지 않은 경우 일부를 연기 할 수 있으며 기본 데이터를 온라인으로 빠르게 가져 오는 것이 더 중요 할 수 있습니다).

파티션이 논리적이 아닌 물리적 파티션 인 경우 다른 프로세스가 다른 파티션을 동시에 채우도록하여 시간을 확보 할 수 있습니다 (물론 TABLOCK/를 사용할 수 없음을 의미 함 TABLOCKX). 이것은 소스가 중복 / 잠금 등을 선택하지 않고 여러 프로세스를 선택하고 작업의 측면을 더 느리게 만드는 데 적합하다고 가정합니다 (힌트 : 대상의 파티셔닝 구성표에 적합한 소스에서 클러스터형 인덱스 만들기).

BCP OUT/BCP IN 와 같이 더 원시적 인 것을 고려할 수도 있습니다 .

나는 이것을 돕기 위해 SSIS로 뛰어들 것임을 모른다. 아마도 약간의 효율성이 있을지 모르지만 그 노력이 저축을 정당화한다는 것을 모르겠습니다.


2
데이터가 정렬되지 않은 경우 인덱스 (예 : 클러스터형 인덱스)를 맹목적으로 삭제하지 마십시오. 인덱스를 삭제하고 클러스터형 인덱스를 다시 만들려고하면 디스크 공간과 시간이 많이 걸리기 때문에 큰 실수가 될 수 있습니다. 나는 그런 실수를 경험 한 최초의 사람이 아닙니다. 이 기사 sqlmag.com/t-sql/… 의 "계획 B"설명을 보십시오 . 저자도 같은 문제가있었습니다.
jyao

10

SSIS 관점에서 문제를 보면 이것이 너무 오래 걸린 이유는 배치를하지 않았기 때문이라고 생각합니다. 이로 인해 SSIS 파이프 라인을 채우는 행이 너무 많아 져 SSIS 성능이 저하 될 수 있습니다. 해야 할 일은 배치 당 행 설정과 가능한 최대 삽입 커밋 크기를 변경하는 것입니다. 이제이 설정도 SSIS 서버에서 사용할 수있는 메모리 양에 따라 달라집니다. SQL Server 인스턴스의 디스크 속도는 얼마입니까? 이를 수행하는 가장 좋은 방법은 테스트입니다. 예를 들어 10,000을 사용할 수 있습니다. 이렇게하면 한 번에 배치를 서버 10,000으로 보내 파이프 라인이 과도하게 채워지지 않도록하고이 프로세스를 더 빠르게 실행하는 데 도움이됩니다. 이 설정은 OLEDB 대상에서 설정됩니다.

OLEDB 대상

문제가 발생하면 @AaronBertrand가 제안한대로 테이블에 인덱스 나 제약 조건을 추가하거나 제거 / 재 추가 할 때와 같이 수행 전후에 SQL 실행 작업을 추가 할 수도 있습니다.


1
dba.stackexchange.com/questions/141430/… : DBA.SE의 다른 곳에 "빠른로드"가 포함되는 것에 대한 훌륭한 의문이 있습니다 .
모든 거래의 존
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.