【发布时间】:2016-05-17 15:48:27
【问题描述】:
使用代码
Using bcp As New SqlBulkCopy(destConnection)
bcp.DestinationTableName = "myOutputTable"
bcp.BatchSize = 10000
bcp.WriteToServer(reader)
End Using
其中 reader 本质上是一个 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)数据运行到输出表(大约
但是如果我在更大的块中运行,比如 45k,(或者让进程运行整个 200k),碎片会变成 99%+。
准确地说,如果我在 39,773 中运行,我得到
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,以 18686 开头的系列与以 18906 开头的系列交错,导致超过 99% 的碎片。
那么,问题是在更大的数据块中运行时,是什么导致索引这样构建?
【问题讨论】:
标签: sql sql-server indexing sqlbulkcopy