更新集超过2000万行?

时间:2015-08-03 19:40:34

标签: sql sql-server tsql

我在这一年中每个月都有一张表,在该表中(其中包括)25列用于自定义数据。只有前8个数据列被索引,我们已将数据插入到第21列,他们现在想要进行通配符搜索。我无法为第21列创建索引,因为应用程序不允许对GUI中前8个数据列进行通配符搜索。

我尝试运行以下命令,但是当事务日志已满时超时,之后将其更改为无限制增长,因为它设置为最大134 GB。

UPDATE CentralContact.dbo.Spd_month_1 
SET p1_value = p21_value 
WHERE dbs_id ='190'

是否有更快的方法,因为每个表包含超过2000万条记录?

3 个答案:

答案 0 :(得分:2)

即使你在笔记本电脑上运行,也不会有很多行。我的Lenovo x1(SSD + 8GB RAM)上有几亿行的测试表。我的服务器有几十亿行的表(非分区)。

由于事务日志已满,您的更新查询超时并不是真正的性能问题。看起来您最近还没有备份事务日志,或者行很大,即使是一个大事务也填满了tlog。有几个选项需要考虑:

  1. 备份事务日志以释放所有先前已提交事务的空间。如果你最近没有这样做,它可能是现在最好的事情。在线查找SQL Server书籍,了解有关如何执行此操作的详细信息。在134GB,这是一个相当大的tlog,如果自初始创建以来自动化,你可能有太多的虚拟日志文件和大量的物理碎片 - 两者都会对性能产生重大负面影响(如果你正在运行SSD然后物理碎片是好的)。此外,每个自动增长都会变得更糟,因为在使用之前需要初始化Tlog空间,因此您需要初始化更大和更大的块。强烈考虑消除tlog并在'#34;合理的"中重新创建。当你得到维护窗口时,从头开始大小。

  2. 将更新分解为几个较小的事务。根据架构的其余部分,这可能也可能不容易。如果存在具有某种单调值的列(例如时间戳,日期,标识,ID等),则可以一次轻松更新范围。具有少量唯一值的列也很有帮助。请注意,在进行更改时,不要添加或更新一堆新值。如果您不是24x7全天候操作,则在单用户模式下锁定数据库以进行更新和验证是最容易解决的问题。

答案 1 :(得分:1)

执行所需操作的最简单方法可能是使用视图。首先,重命名该表,然后创建一个视图以使列变为:

sp_rename 'CentralContact.dbo.Spd_month_1 ', '_Spd_month_1'

create view Spd_month_1 as
    select p_col21 as p_col1, . . .
    from _Spd_month_1;

视图非常简单,因此可用于更新。您没有删除原始表,因此保留了约束,外键引用,触发器等。应用程序应该能够像表格一样轻松地访问视图。

更新的问题是每一行都被更改,因此每行都会被记录。即使SQL Server的最小日志记录功能也是如此。解决此问题的一种方法是将表复制到另一个位置,截断它,然后重新插入数据。但是,对于134 GB,我会尽量减少任何数据移动操作。

答案 2 :(得分:1)

你可能想要使用的是来自Pentaho的Kettle(或“勺子”)。请查看here

这样做有“作业”和“转换”以及您可以维护各种服务器和数据库的其他自动化流程。

它所做的一件事是批量更新。您可以选择要更新的整个记录​​集,然后每隔几秒为其提供1000条记录,以便更新和提交。这样就无法锁定表格。

我一直使用它,并且在繁忙的流量/重载表上进行大量更新时,绝不会建议使用除此方法之外的任何其他内容。