2010-06-25 2 views
1

현재 많은 소스에서 수 GB의 데이터를 매일 가져 오는 대용량 데이터웨어 하우스가있는 프로젝트에서 작업하고 있습니다. 우리는 다양한 형식과 구조를 가진 많은 파일을 모두 기본 테이블로 가져 와서 저장된 procs를 통해 변환/피벗합니다. 이 부분은 잘 작동합니다. 그러나 초기 수입은 매우 느립니다.대용량 가변 열 데이터 파일을 SQL Server로 옮겨서 삽입 할 때 성능 문제가 발생했습니다.

열이 파일마다 완전히 다를 수 있으므로 SSIS 파일 연결 관리자를 사용할 수 없으므로 행과 열의 데이터를 두 개의 기본 테이블로 변환하는 C#의 사용자 지정 개체 모델이 있습니다. 하나는 열 이름 용이고 다른 하나는 속성 테이블의 레코드와 관련된 각 셀의 실제 데이터 용입니다.

예 - 데이터 파일 :

alt text http://i50.tinypic.com/2ypkgf9.jpg

예 - DB 테이블 :

alt text http://i45.tinypic.com/2iqhkoy.jpg

은 SQL 삽입이에 값을 모든 데이터 행을 반복하고 추가하여 현재 수행 SQL 캐릭터 라인 이것은 큰 동적 문자열을 구성하며,이 문자열은 SqlCommand를 통해 마지막에 실행됩니다.

1MB 파일에서 실행되는 경우에도 약 1 분이 걸리기 때문에 큰 파일 (200MB 등)의 경우 한 파일을 처리하는 데 몇 시간이 걸립니다. 나는 성능 향상과 프로세스 속도 향상을 위해 인서트에 접근하는 다른 방법에 대한 제안을 찾고 있습니다.

문자열의 크기와 문자열에 나타나는 SQL 명령의 수를 줄이기 위해 루프의 구조를 할 수있는 몇 가지 방법이 있지만 이상적으로는 더 깔끔하고 견고한 방법을 찾고 있습니다. 제가 자신을 잘 설명하지 않았다면 사과 드리며, 필요한 경우 더 자세하게 설명해 드리겠습니다.

이 프로세스의 속도를 높이는 방법에 대한 아이디어가 있으십니까?

답변

1

동적 문자열이 느리게됩니다. 각 SQLCommand는 데이터베이스에 대한 별도의 호출입니다. 당신은 많이 대량 삽입 작업으로 출력을 스트리밍 더 나은 있습니다.

모든 파일이 다른 형식이므로 EAV 데이터베이스 형식으로 코드를 파싱하고 unpivot해야합니다.

그러나 출력이 일관된 스키마에 있기 때문에 개별 연결 관리자와 기본 제공 unpivot 연산자를 사용하거나 스크립트 출력에서 ​​공통 출력의 데이터 흐름에 여러 행을 추가하는 것이 좋습니다. 현재 각 INSERT INSERT INSERT INSERT INSERT INSERT INSERT INSERT INSERT INSERT INSERT 같은 모든 입력 행에 대한 작업을 수행하는 것처럼).

즉데이터를 읽고 스크립트 소스에서 FileID, RowId, AttributeName 및 Value를 여러 행에 할당합니다 (코드에서 피벗 해제를 수행하지만 다양한 수의 삽입을 생성하는 대신 다양한 행 수를 삽입하는 것입니다. 입력 행을 기반으로하는 데이터 흐름으로).

그런 다음 조회를 통해 AttributeName에서 AttributeID (유효하지 않은 속성으로 행 오류 발생)로 이동하십시오.

OLEDB 대상으로 직접 스트리밍하면 훨씬 빨라야합니다.

+0

이 SSIS 패키지 최적화를 마침내 살펴볼 기회를 얻었으므로이 솔루션에 대한 정답을 변경했습니다.이 솔루션은 지금까지 최적의 솔루션을 제공했습니다. 다른 솔루션은 도움이되었고 일을 개선하여 투표했지만 투표율이 99 % 향상되었습니다. 따라서 정답으로 표시하는 것이 공정한 것처럼 보였습니다. – GShenanigan

+1

@fat_tony 최신 독자를 위해 시간이 있다면 구현 한 최종 솔루션의 구조에 대한 자세한 내용을 나타 내기 위해 질문을 업데이트 할 수 있습니까? 내 대답은 정확한 해결책을 설명하지 못했습니다. –

+0

좋습니다. 나는 기회를 얻었을 때 내 질문을 업데이트하고 해결책에 대해 좀 더 자세하게 설명 할 것이다. 건배에 대한 환호, 죄송합니다. 응답주기에 너무 오래 걸렸습니다! – GShenanigan

1

하나의 생각 - 적절한 속성 값을 찾기 위해 반복적으로 데이터베이스로 돌아가십니까? 그렇다면 반복되는 쿼리를 클라이언트 측에서 유지하는 레코드 집합에 대한 쿼리로 전환하면 작업 속도가 빨라집니다.

이것은 이전에 수행 한 작업입니다. 참조 테이블이 4 개 포함되었습니다. 로컬 레코드 세트를 만들고 적절하게 필터링하면 2.5 시간에서 약 3 분으로 프로세스가 빨라졌습니다.

+0

안녕하세요. 예. 속성 ID 등을 찾기 위해 매번 실행되는 반복 된 쿼리가 많이 있습니다. 미리로드해야하는 등의 이유로 확실히 도움이됩니다. 나는 아직도 우리가 할 수있는 일이 더 많다고 생각하는데 동적 문자열을 만드는 것보다 실제로 데이터를 삽입하는 더 좋은 방법이 있는지 궁금합니다. – GShenanigan

+0

텍스트 파일을 작성하고 일괄 가져 오기 (파일 스트림) 루틴을 호출하는 과정을 거치지 않고 솔직히 말하면 의심 스럽습니다. 그리고 그들은 추가적인 실패 지점을 가진 시스템을 만들 것입니다. –

+0

그래, 그건 사실 말이야. 나는 오늘 오후에 약간의 변화를 시도하여이 모든 일이 어떻게 진행되는지 알려 드리려고합니다. 감사합니다 – GShenanigan

1

각 데이터베이스 내에 필요한 참조 테이블을 저장하고 데이터베이스 끝에서 모든 조회를 수행하는 이유는 무엇입니까? 또는 키가 필요한 각 데이터베이스에 테이블 형식을 전달하고 모든 참조 데이터를 하나의 중앙 데이터베이스에 저장 한 다음 거기에서 조회를 수행하는 것이 더 나을 수도 있습니다.

관련 문제