如何加快群集列的大规模更新?

Jef*_*ang 7 sql sql-server indexing performance

我有一个非常大的表:超过2000万行,我需要更新大约5% - 或100万行.

不幸的是,我正在更新用作聚簇索引的(int)列.

我的问题是:更新这些行的最快方法是什么?

我试过直接更新行:

update t1
set t1.groupId = t2.groupId
from
    table t1
join newtable t2 on t1.email = t2.email
Run Code Online (Sandbox Code Playgroud)

但这需要太长时间(我在3小时后停止了)

我假设这是因为整个行(有2个日期时间,2个varchars和2个int)正在为每次更新移动.

如果我首先删除聚簇索引,然后执行更新,然后重新创建聚簇索引,该怎么办?会更快吗?

注意:我在电子邮件上有一个非聚集索引,以防有人认为它是查询的选择部分很慢.不是.

Jef*_*ang 8

这就是我所做的(而且速度要快得多):

  1. 我删除了聚集索引.
  2. 我还删除了外键引用(另外两个int列).
  3. 我运行了更新语句
  4. 我重新创建了索引,这比预期的要快.(这是我先问过SO的原因).

这使整个过程缩短到几秒钟. 是的,约15秒内约100万行.

第二步是至关重要的,因为外键强制更新在相关表上执行某种线程,每个表都有大量行.

由于这些外键查找,物理读取的数量增加了两倍.

我不确定为什么SQL Server需要这样做,但我的猜测是它仍然执行完整性检查,即使我没有更新该列但我正在移动整行(群集列更新).


作为附注,我还尝试批量运行更新:

update top(1000) t1
set t1.groupId = t2.groupId
from
    table t1
join newtable t2 on t1.email = t2.email
Run Code Online (Sandbox Code Playgroud)

这很好(并且似乎每批可扩展到大约10K),但每批次仍然是1-2分钟.


总之,我已经了解到,对于批量更新,暂时删除索引可能非常有用.