SqlBulkCopy를 사용하여 대량의 데이터를 데이터베이스간에 이동할 때 왜 높은 분할이 발생합니까?

indexing sql sqlbulkcopy sql-server

문제

코드 사용하기

Using bcp As New SqlBulkCopy(destConnection)
     bcp.DestinationTableName = "myOutputTable"
     bcp.BatchSize = 10000

     bcp.WriteToServer(reader)
End Using

어디 리더가 본질적으로 IDataReader 테이블에, 200k 행 정도를 포함 읽고 있습니다.

입력 테이블은 다음과 같습니다.

CREATE TABLE [dbo].[MyTable](
    [TagIndex] [SMALLINT] NOT NULL,
    [TimeStamp] [DATETIME] NOT NULL,
    [RawQuality] [SMALLINT] NOT NULL,
    [ValQuality] [SMALLINT] NOT NULL,
    [Sigma] [REAL] NULL,
    [Corrected] [REAL] NULL,
    [Raw] [REAL] NULL,
    [Delta] [REAL] NULL,
    [Mean] [REAL] NULL,
    [ScadaTimestamp] [DATETIME] NOT NULL
) ON [PRIMARY

그리고 타임 스탬프에 의해 주문됩니다.

출력 테이블은 동일한 구조로되어 있으며 다음 색인이 있습니다 (프로세스 시작시 비어 있음).

CREATE CLUSTERED INDEX [MyOutputTable_Index] ON [dbo].[MyOutputTable]
(
    [TimeStamp] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO

한 번에 작은 (ish) 양의 데이터를 출력 테이블로 실행하도록 프로세스를 인위적으로 조절하면 (<35k 정도) 조각화가 5 % 미만이되며 모든 것이 정상입니다.

하지만 더 큰 덩어리로 실행하면 (예 : 45k) (또는 프로세스가 전체 200k를 실행하도록) 조각화가 99 % +가됩니다.

정확히 39,773에서 실행하면 <5 %의 조각화가 발생하지만 39,774에서는 99 %의 조각화가 발생합니다. 인덱스에 할당 된 페이지를 조사하면 DBCC 페이지를 사용하여 다음을 볼 수 있습니다.

FileId  PageId  Row Level   ChildFileId ChildPageId TimeStamp (key)
1       18937   0   1       1           18906       2015-10-22 01:37:32.497
1       18937   1   1       1           18686       2015-10-22 01:38:12.497
1       18937   2   1       1           18907       2015-10-22 01:38:47.497
1       18937   3   1       1           18687       2015-10-22 01:39:27.497
1       18937   4   1       1           18908       2015-10-22 01:40:02.497
1       18937   5   1       1           18688       2015-10-22 01:40:42.497
1       18937   6   1       1           18909       2015-10-22 01:41:17.497
1       18937   7   1       1           18689       2015-10-22 01:41:57.497
1       18937   8   1       1           18910       2015-10-22 01:42:32.497

ChildPageId 열을 보면 번호가 연속적으로 실행되지 않음을 알 수 있습니다.

예를 들어, 18906 다음에 18686이 이어지며 18907이 시작되고 189086은 18906으로 시작하는 시리즈로 인터리브되어 1896으로 시작되며 조각화가 99 % 이상 발생합니다.

그래서 문제는 더 큰 데이터 덩어리에서 실행될 때 인덱스가 이렇게 생성되도록 만드는 것입니다.

인기 답변

더 많은 데이터가 없어도 알 수 없지만 클러스터 된 인덱스 인 타임 스탬프가 원인입니다. 출력 테이블에 보내기 전에이 필드로 데이터 정렬을 시도하십시오.



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