使用代码
Using bcp As New SqlBulkCopy(destConnection)
bcp.DestinationTableName = "myOutputTable"
bcp.BatchSize = 10000
bcp.WriteToServer(reader)
End Using
其中reader是本质上是一个IDataReader,它读取包含20万行左右的表。
输入表如下所示
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
并由TimeStamp订购。
输出表具有相同的结构,并具有以下索引(在过程开始时为空)。
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
人工节流该过程以一次将少量数据运行到输出表中(大约
但是,如果我以较大的块(例如45k)运行(或让该进程运行整个200k),则碎片将变为99%+。
确切地说,如果我在39,773中运行,则得到而且,如果我调查在索引中分配的页面,则可以使用DBCC PAGE看到以下内容。
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%的碎片。
因此,问题是什么导致在较大数据块中运行时以这种方式建立索引?
最佳答案
没有更多数据很难说,但我敢打赌,您的时间戳是聚集索引,这是造成这种情况的原因。在发送到输出表之前,请尝试按此字段对数据进行排序。