따라서 준비 테이블에서 데이터를 가져 와서 데이터 마트로 옮기는 간단한 대량 삽입 프로세스가 있습니다.
이 프로세스는 “배치 당 행 수”에 대한 기본 설정이 포함 된 간단한 데이터 흐름 작업이며 옵션은 “tablock”및 “check check constraint”입니다.
테이블이 상당히 큽니다. 데이터 크기 201GB 및 49GB의 인덱스 공간을 가진 587,162,986 테이블의 클러스터형 인덱스는 다음과 같습니다.
CREATE CLUSTERED INDEX ImageData ON dbo.ImageData
(
DOC_ID ASC,
ACCT_NUM ASC,
MasterID ASC
)
기본 키는 다음과 같습니다.
ALTER TABLE dbo.ImageData
ADD CONSTRAINT ImageData
PRIMARY KEY NONCLUSTERED
(
ImageID ASC,
DT_CRTE_DOC ASC
)
이제 우리는 BULK INSERT
SSIS를 통해 매우 느리게 실행 되는 문제를 겪고 있습니다. 1 시간 동안 백만 행 삽입 테이블을 채우는 쿼리는 이미 정렬되어 있으며 채우는 데 1 분이 걸리지 않습니다.
프로세스가 실행 중일 때 쿼리가 BULK 삽입을 기다리고 5 ~ 20 초가 걸리고 대기 유형이 표시되는 것을 볼 수 PAGEIOLATCH_EX
있습니다. 프로세스는 INSERT
한 번 에 약 천 행만 가능합니다.
어제 UAT 환경에 대해이 프로세스를 테스트하는 동안 같은 문제가 발생했습니다. 프로세스를 몇 번 실행 하고이 느린 삽입의 근본 원인을 확인하려고했습니다. 그런 다음 갑자기 5 분 안에 시작되었습니다. 그래서 나는 같은 결과로 몇 번 더 실행했습니다. 또한 5 초 이상 대기 한 벌크 인서트의 수는 수백에서 약 4로 떨어졌습니다.
이것은 우리가 활동을 크게 떨어 뜨린 것과 같지 않기 때문에 당황합니다.
지속 시간 동안 CPU가 부족합니다.
속도가 느릴 때 디스크 대기 시간이 줄어 듭니다.
실제로 디스크 대기 시간은 프로세스가 5 분 이내에 실행되는 시간 동안 증가합니다.
그리고이 프로세스가 제대로 실행되지 않는 동안 IO는 훨씬 낮아졌습니다.
이미 확인했으며 파일이 70 % 만 찼으므로 파일 크기가 증가하지 않았습니다. 로그 파일의 이동률은 여전히 50 %입니다. DB가 단순 복구 모드에 있습니다. DB에는 파일 그룹이 하나만 있지만 4 개의 파일로 분산되어 있습니다.
그래서 내가 궁금한 것은 A : 왜 대량 삽입물에서 이렇게 큰 대기 시간을 보았습니까? B : 어떤 종류의 마술이 일어 났어?
사이드 노트. 오늘도 쓰레기처럼 뛰고 있습니다.
UPDATE 현재 파티션되어 있습니다. 그러나 그것은 어리석은 방법으로 이루어집니다.
CREATE PARTITION SCHEME [ps_Image] AS PARTITION [pf_Image]
TO ([FG_Image], [FG_Image], [FG_Image], [FG_Image])
CREATE PARTITION FUNCTION [pf_Image](datetime) AS
RANGE RIGHT FOR VALUES (
N'2011-12-01T00:00:00.000'
, N'2013-04-01T00:00:00.000'
, N'2013-07-01T00:00:00.000'
);
기본적으로 모든 데이터는 4 번째 파티션에 남습니다. 그러나 모두 동일한 파일 그룹으로 이동하기 때문입니다. 데이터는 현재 해당 파일에서 상당히 고르게 분할됩니다.
업데이트 2
프로세스가 제대로 실행되지 않을 때의 전체 대기 시간입니다.
이것은 프로세스를 제대로 실행할 수 있었던 기간 동안의 대기 시간입니다.
스토리지 서브 시스템은 SAN을 포함하지 않고 로컬로 연결된 RAID입니다. 로그가 다른 드라이브에 있습니다. RAID 컨트롤러는 1GB 캐시 크기의 PERC H800입니다. (UAT의 경우) Prod는 PERC (810)입니다.
우리는 백업없이 간단한 복구를 사용하고 있습니다. 매일 밤 프로덕션 사본에서 복원됩니다.
IsSorted property = TRUE
데이터가 이미 정렬되어 있으므로 SSIS 에서도 설정 했습니다.
답변
원인을 알 수는 없지만 BULK INSERT 작업의 배치 당 기본 행은 “모두”라고 생각합니다. 행 제한을 설정하면 작업을보다 소화하기 쉽게 만들 수 있습니다. 이것이 옵션입니다. (여기서 계속해서 Transact-SQL “BULK INSERT”설명서를보고 있으므로 SSIS를 사용할 수 없습니다.)
작업을 여러 개의 X 행 배치로 분할하는 효과가 있으며 각 행은 별도의 트랜잭션으로 작동합니다. 오류가있는 경우 완료된 배치는 대상 테이블에 커밋 된 상태로 유지되고 중지 된 배치는 롤백됩니다. 그것이 당신이하고있는 일에 견딜 수 있다면, 즉 나중에 다시 실행하고 따라 잡을 수 있습니다.
모든 현재 삽입을 하나의 테이블 파티션에 넣는 파티션 함수는 잘못된 것이 아니지만 동일한 파일 그룹의 파티션으로 파티션을 나누는 것이 얼마나 유용한 지 알 수 없습니다. 그리고 datetime을 사용하는 것은 좋지 않으며 SQL Server 2008 이후 명시 적 CONVERT 수식이 없으면 datetime 및 ‘YYYY-MM-DD’에 실제로 손상됩니다 (SQL은 이것을 YYYY-DD-MM으로 유쾌하게 취급 할 수 있습니다 : 농담이 아닙니다 : 당황하지 마십시오. 그냥 ‘YYYYMMDD’, 고정 : 또는 CONVERT (날짜 시간, ‘YYYY-MM-DDT00 : 00 : 00’, 126)로 변경하십시오.) 그러나 날짜 값 (년 또는 정수 + 연도)에 프록시를 사용하면 더 잘 작동 할 것이라고 생각합니다.
다른 곳에서 복사하거나 여러 데이터 마트에서 복제 된 디자인 일 수 있습니다. 이것이 진정한 데이터 마트 인 경우, 데이터웨어 하우스에서 덤프하여 부서 관리자에게 재생할 데이터를 제공합니다. 데이터는 다른 곳으로 전송되지 않으며 데이터 사용자와 관련하여 읽기 전용입니다. 그렇다면 파티션 기능을 제거하거나 네 번째 파티션에 모든 새 데이터를 명시 적으로 변경하여 아무도 신경 쓰지 않을 것으로 생각됩니다. (아마도 아무도 신경 쓰지 않는지 확인해야합니다.)
나중에 파티션 1의 내용을 삭제하고 더 많은 새로운 데이터를위한 새 파티션을 만들 계획이있는 디자인처럼 느껴지지만 여기서는 그렇게 들리지 않습니다. 적어도 2013 년 이후에는 일어나지 않았습니다.
답변
나는 가끔 큰 파티션 테이블에 대한 인서트에서 이와 같은 산발적 인 극단적 인 둔화를 보았습니다. 대상 테이블 통계를 업데이트 한 다음 다시 실행 해 보셨습니까? 대기 시간이 길어지면 통계가 나빠질 수 있으며 테스트 중 특정 시점에서 통계 업데이트가 트리거 된 경우 속도 증가를 설명합니다. 생각하고 쉽게 테스트 할 수 있습니다.