SqlBulkCopy로 삽입 된 행 가져 오기

linq-to-sql sqlbulkcopy sql-server transactions

문제

내 Linq 중 일부를 SqlBulkCopy를 사용하는 Sql 코드로 전환하려고하는데 문제는 두 개의 테이블에 여러 수천 개의 행을 두 번 삽입해야한다는 것입니다.

이 서비스는 10,000 링크 (사이트 맵, 백 링크 빌더 등에서 가져온)의 일괄 처리를 가져 와서 집계를 위해 피드 당 X의 RSS 피드로 자릅니다. 문제는 이미 3200 만 개의 행이 있다는 것 입니다. SQL 삽입에 linq을 수행하는 경우 10,000 링크를로드하는 데 5에서 10 분 사이의 사이트 트래픽에 따라 소요됩니다.

구조는 매우 기본입니다.

피드 varchar (1000), 설명 varchar (1000), 게시 된 datetime, 집계 datetime null, ShortCode varchar (8) [antiquated, 더 이상 삽입되지 않지만 레거시 데이터에 사용]

항목 : varchar (1000), Published datetime, ShortCode varchar (8) [구식이며 더 이상 삽입되지 않지만 레거시 데이터에 사용됨], ShortId bigint (PK), FeedId bigint (FK), Title varchar null [동일하게 삽입 된 ID 뒤에 업데이트 됨 (파티셔닝에 사용됨)]

FutureItems : ID bigint (PK), FeedId bigint (FK), Title varchar (1000), 설명 varchar (1000), Published datetime, ShortCode varchar (8) [구식, 더 이상 삽입하지 않지만 레거시 데이터에 사용], ShortId bigint null [동일하게 삽입 된 ID 뒤에 업데이트 됨 (파티셔닝에 사용됨)]

OldItems : ID bigint (PK), FeedId bigint (FK), Title varchar (1000), 설명 varchar (1000), Published datetime, ShortCode varchar (8) [구식, 더 이상 삽입하지 않지만 레거시 데이터에 사용], ShortId bigint null [동일하게 삽입 된 ID 뒤에 업데이트 됨 (파티셔닝에 사용됨)]

따라서 피드 크기가 20 인 경우 피드 테이블에 500 개의 삽입을 가져온 다음 항목 테이블에 10000을 삽입 한 다음 업데이트를 실행하여 ShortId를 Id와 동일하게 설정합니다. 밤에 한 번 작업을 실행하면 데이터가 다른 두 테이블로 분리되고 이후 항목이 Items 테이블로 이동합니다.

나는 SqlBulkCopy가 mintues의 문제로 2 천만 개의 행을 처리 할 수 ​​있다고 읽었지만, FK Constraint를 사용하여 여러 테이블로 처리하는 좋은 예제를 찾을 수 없습니다.

우리의 SQL 서버는 특히이 응용 프로그램을위한 "괴물"입니다. SQL 2008 R2 웹, Windows 2008 R2 Enterprise, 12GB 램, 듀얼 4 ​​코어 Xeons @ 2.8ghz입니다.

우리의 웹 서버는 데이터베이스 서비스가없는 복제품입니다.

링크를 삽입 할 때 CPU가 약 85 % 실행되고 데이터베이스가 RAM을 가득 채 웁니다.

SqlBulkCopy가 좋지 않다면 어떤 제안이라도 환영합니다. 우리는 화를 내고있는 고객에게 돈을 지불하고 DBA가 아닙니다. 평범한 프로그래머입니다.

수락 된 답변

SqlBulkCopy는 실제로 일반적인 삽입보다 빠릅니다. 그러나 초당 1000 개의 인서트를 수행하는 작업을 10000 / 초의 작업으로 변환 할 수있는 속도는 더 빠릅니다. 10 분 안에 10000 개의 링크 만 할 수 있다면 다른 문제가 발생해야합니다. 대량 복사가 해결되지 않을 수 있습니다.

먼저 10000 개의 링크를 삽입하는 데 너무 오래 걸리는 이유 를 먼저 조사해야합니다. 이해가 끝난 후에 만 ​​SqlBulkCopy로 옮기는 것이 해결책인지 판단 할 수 있습니다. 저는 DBA가 아니지만 SQL Server 성능 문제를 해결할 수있는 'dbaish'백서를 알려 드릴 것입니다 : 대기 및 대기열 . 이것은 쿠키 커터 제조법 솔루션이 아니며 실제로는 SQL Server에서 성능 병목 현상을 식별하는 방법을 알려주는 방법론입니다.

그리고 귀하의 질문에 대답 : 제약 조건이있을 때 SqlBulkCopy를 어떻게 사용합니까? 보다 일반적인 질문은 제약 조건이있을 때 대량 삽입 작업을 수행하는 방법입니다. 심각한 볼륨의 경우 실제로 제약 조건을 비활성화하고 대량 업로드를 수행 한 다음 제약 조건을 다시 활성화합니다. 다운 타임을 최소화하면서보다 효율적인 온라인 운영을 위해 (제약 조건이 비활성화 된 기간 동안 데이터베이스는 기본적으로 '다운'상태 임) 다른 전략을 사용합니다. 즉, 스테이징 테이블에서 데이터를 사전로드하고 유효성을 검사 한 다음 파티션 전환 을 사용하여 효율적으로 데이터 전송을 참조하십시오.


인기 답변

평범한 대량 삽입물을 사용하는 것의 실제 문제는 다른 테이블의 초기 삽입물에서 피드 ID가 필요하다는 것입니다. 여기 내가하는 일이있다. 스테이징 테이블에 삽입하려면 대량 삽입물을 사용하십시오. 그런 다음 저장된 proc을 사용하여 set 기반 방식으로 실제 테이블에 대한 삽입을 수행합니다. 피드 테이블에 대한 초기 삽입에서 출력 절을 사용하여 다른 테이블에 대한 삽입에 필요한 피드 ID로 테이블 변수를 가져올 수 있습니다.



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