Sql 在大量使用的大型表上运行更新

Sql 在大量使用的大型表上运行更新,sql,Sql,我在SQLServer2005中有一个很大的表(约1.7亿行,2个nvarchar和7个int列),它不断地插入到数据库中。从性能的角度来看,一切都正常,但每隔一段时间,我必须更新表中的一组行,这会导致问题。如果我更新一小部分数据,它可以正常工作,但是如果我必须更新一组40000条左右的记录,则需要大约3分钟的时间和表上的块,因为插入开始失败,这会导致问题 如果我只是运行一个select来获取需要更新的数据,我将在大约2秒钟内获取40k条记录。只是更新要花很长时间。这反映在更新的执行计划中,其中

我在SQLServer2005中有一个很大的表(约1.7亿行,2个nvarchar和7个int列),它不断地插入到数据库中。从性能的角度来看,一切都正常,但每隔一段时间,我必须更新表中的一组行,这会导致问题。如果我更新一小部分数据,它可以正常工作,但是如果我必须更新一组40000条左右的记录,则需要大约3分钟的时间和表上的块,因为插入开始失败,这会导致问题

如果我只是运行一个select来获取需要更新的数据,我将在大约2秒钟内获取40k条记录。只是更新要花很长时间。这反映在更新的执行计划中,其中聚集索引更新占用90%的成本,而获取行的索引查找和top操作符占用10%的成本。我正在更新的列不是任何索引键的一部分,因此它不像是在重新组织任何内容

有人对如何加快这一进程有什么想法吗?我现在的想法是编写一个服务,只需查看何时必须进行这些更新,收回必须更新的记录,然后循环并逐个更新它们。这将满足我的业务需求,但这是另一个需要维护的模块,如果我能从DBA的角度解决这个问题,我会很高兴

谢谢你的任何想法

mos蛮力(也是最简单的)方法是拥有一个基本的服务,正如您所提到的。其优点是能够随服务器负载和/或数据负载进行扩展

例如,如果您有一组必须尽快进行的更新,则可以增大批大小。相反,对于不太重要的更新,如果每次更新花费“太长”的时间来减轻数据库的一些压力,那么更新“服务器”可能会变慢


这种“心跳”过程在系统中非常常见,在正确的情况下可能非常强大。

实际上,如果您更新nvarchar列,它可能会重新组织页面。 根据更新对这些列所做的操作,它们可能会导致记录增长到大于更新前为其保留的空间。 (请参见解释,nvarchar存储在。)

假设一条记录在nvarchar中保存了一个由20个字符组成的字符串-这需要20*2+2(指针为2)字节的空间。这是在表的初始插入时写入的(基于索引结构)。SQL Server将只使用nvarchar实际占用的空间

现在进行更新并插入40个字符的字符串。哎呀,索引的叶子结构中的记录空间突然太小了。因此,关闭记录到另一个物理位置,旧位置的指针指向更新记录的实际位置

这会导致索引过时,因为整个物理结构需要更改,所以您会看到很多索引工作在幕后进行。很可能导致独占表锁升级


不知道如何最好地处理这个问题。就我个人而言,如果可能的话,我会使用独占表锁,删除索引,进行更新,重新编制索引。因为您的更新有时会导致索引过时,所以这可能是最快的选择。但是,这需要一个维护窗口。

您的分析程序显示更新聚集索引需要时间。更新时数据的大小是否更改?似乎varchar正在驱动数据重新组织,这可能需要更新索引指针(正如KMB已经指出的那样)。在这种情况下,您可能希望增加数据和索引页上的可用大小百分比,以便数据和索引页可以在不重新链接/重新分配的情况下增长。由于更新是一个IO密集型操作(与读取不同,读取可以缓冲),因此性能也取决于几个因素

1) 您的表是按数据分区的吗2)整个表是否位于同一个SAN磁盘中(或者SAN条带化良好吗?)3)事务日志记录有多详细。事务日志的缓冲区大小是否可以增加以支持更大的日志写入以支持大量插入


使用哪种API/语言也很重要?e、 g JDBC支持批量更新功能,如果您正在执行多个更新,则该功能会使更新稍微有效。

您应该将更新批量到多个更新中(例如一次10000个,测试!),而不是40k行中的一个大更新

这样可以避免表锁,SQL Server在转换为表锁之前只会取出5000个锁(页或行),即使这样也不是很可预测的(内存压力等)。在此版本中进行的较小更新至少可以避免您遇到的并发问题

您可以使用服务或消防软管光标批处理更新

有关更多信息,请阅读:

希望这有帮助


Robert

你能发布表定义(包括主键、索引等)、表上的任何触发器以及实际的更新查询本身吗?@Adrian-但是如果更新的字段不在聚集索引(或显然是任何其他索引)中,为什么执行计划会显示聚集索引更新?@Dems我猜,纯粹基于手头数据的猜测是,它正在磁盘上移动表数据,因此它正在更新指向数据实际移动位置的指针。为什么会这样做。。。不知道;也许屋宇署正试图优化某物。正常情况下,我不希望每次都发生这种情况!有一个网站专门介绍“事物的DBA方面”,你也可以尝试在那里发布你的问题。哎呀,这是我第一次发布到stack上,我觉得当问题得到回复时,我会收到电子邮件。那没有发生很抱歉我不在这里提供任何额外的信息。我对下面的一些答案发表了评论。我最终写了这个服务,因为它满足了我的需求。如果还有人想查看table/update语句,