批量插入时间差异很大


13

因此,我有一个简单的批量插入过程,可以从暂存表中获取数据并将其移入我们的数据集市。

该过程是一个简单的数据流任务,默认设置为“每批行数”,选项为“ tablock”和“无检查约束”。

桌子很大。587,162,986,数据大小为201GB,索引空间为49GB。该表的聚集索引为。

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小时插入一百万行。填充表的查询已经排序,并且要填充的查询需要不到一分钟的时间才能运行。

当进程运行时,我可以看到查询正在等待BULK插入,这需要5到20秒的时间,并且显示的等待类型为PAGEIOLATCH_EX。该过程一次只能执行INSERT大约一千行。

昨天,在针对我的UAT环境测试此过程时,我遇到了同样的问题。我运行了几次该过程,试图确定此缓慢插入的根本原因是什么。然后突然之间不到5分钟就开始运行了。所以我又运行了几次,结果都一样。等待5秒或更长时间的散装插入物数量也从数百下降到大约4。

现在,这令人困惑,因为这并不像我们的活动有所减少。

CPU持续时间很短。

中央处理器

速度较慢的时间似乎较少等待磁盘。

等待

实际上,磁盘延迟会在5分钟以内运行该进程的时间内增加。

潜伏

在此过程运行不佳的时期,IO更低。

IO

我已经检查过了,并且文件没有增长,因为文件仅占70%。日志文件仍有50%可用。数据库处于简单恢复模式。DB仅具有一个文件组,但分布在4个文件中。

所以我想知道的是:为什么我看到那些大批量插入的等待时间如此之长。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 这些是流程运行不佳时的总体等待时间。

等待1

这是我能够运行的期间等待的过程,运行良好。

等待2

存储子系统是本地连接的RAID,不涉及SAN。日志位于其他驱动器上。突袭控制器是PERC H800,具有1 GB缓存大小。(对于UAT)Prod是PERC(810)。

我们正在使用没有备份的简单恢复。它将从每晚的生产副本中恢复。

IsSorted property = TRUE由于数据已经排序,因此我们也在SSIS中进行了设置。


ASYNC_NETWORK_IO表示SQL Server正在等待发送到某处的客户端。我想这显示的是SSIS消耗临时表中行的活动。
Max Vernon

PAGEIOLATCH_EXASYNC_IO_COMPLETION指示从磁盘将数据获取到内存需要一段时间。这可能表明磁盘子系统有问题,也可能是内存争用。SQL Server有多少可用内存?
Max Vernon

使用ImageData的表名,您会感到好奇-实际的表定义是什么?如果要提取LOB数据,则可能是缓冲到磁盘(转到BLOBTempStoragePath,如果未定义,它将是执行用户的%TEMP%目录,也称为C驱动器)
billinkc

无法发布表定义,但它是未成像文档的信息。
赞恩

我怀疑这是并行处理问题。我建议您调整MAXDOP(从1到4)并查看一切。另一方面,出于测试目的,我宁愿创建一个BCP命令来替换SSIS并查看是否存在任何区别。
jyao

Answers:


1

我无法指出原因,但我相信BULK INSERT操作的默认每批处理行为“ all”。在行中设置限制可以使操作更易于理解:这就是为什么这样做的原因。(在这里,我继续看一下Transact-SQL的“批量插入”文档,因此对于SSIS来说可能是遥遥无期的。)

它将具有将操作分为多批X行的作用,每行作为一个单独的事务进行操作。如果有错误,则完成的批次将保持提交到目标表中,而停止的批次将回滚。如果您所做的工作是可以忍受的,即您可以稍后重新运行并赶上来,那么请尝试一下。

具有将所有当前插入内容放入一个表分区中的分区功能并没有错,但是我看不到用同一文件组中的分区进行分区有什么用。而且使用datetime的效果很差,并且由于没有显式的CONVERT公式,因此datetime和'YYYY-MM-DD'的使用实际上是很糟糕的,因为自SQL Server 2008起(SQL可能会高兴地将其视为YYYY-DD-MM:不要在开玩笑:不要惊慌,只需将其更改为'YYYYMMDD',固定即可:或CONVERT(datetime,'YYYY-MM-DDT00:00:00',126),我想是)。但我认为使用代理将日期值(年作为整数,或年+季度)进行分区会更好。

可能是从其他地方复制的设计,或者是跨多个数据集市重复的设计。如果这是一个真正的数据集市,那么它是从数据仓库中进行的转储,可以为部门经理提供一些要处理的数据,而不是(您自己)将其发送到其他地方,并且就数据用户而言,可能是只读的,那么,在我看来,您可以删除分区功能-或-不管如何将其更改为显式地将所有新数据放入第四个分区,而且没人会在意。(也许您应该检查没有人在乎。)

感觉就像是一种设计,计划在将来的某个时间删除分区1的内容,并创建另一个新分区以存储更多新数据,但这听起来好像没有发生这种情况。至少自2013年以来从未发生过。


0

我偶尔也会在插入大型分区表时看到这种偶发的极端缓慢现象。您是否尝试过更新目标表统计信息然后再次运行?极端的等待时间可能是由于统计信息不佳而引起的,如果在测试过程中某个时刻触发了统计信息更新,则可以解释速度的提高。只是一个想法和一个容易验证的测试。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.