更改列大小需要很长时间?

u23*_*534 9 sql-server alter-table sql-server-2014

我有一个包含 45M 行(45 GB 数据空间和 2GB 索引空间)的表。我添加了一个新列,它立即完成。

alter table T add C char(25)
Run Code Online (Sandbox Code Playgroud)

然后我发现尺寸太小,所以我运行以下查询。

alter table T alter column C varchar(2500)
Run Code Online (Sandbox Code Playgroud)

它运行了一个小时,并且仍在运行。sp_whoisactive 显示(目前,仍在运行)

reads: 48,000,000
writes: 5,000,000
physical reads: 3,900,000
Run Code Online (Sandbox Code Playgroud)

不是应该很快吗?

Mat*_*DBA 12

假设所有先前创建的列都是固定宽度的,如chardatetime,添加C上面的列只是将其添加到记录的固定宽度部分的末尾(实际上是仅元更改)。但是,将其重新转换为varchar需要将其移动到记录的可变宽度部分,从而强制隐式重建表。Paul Randal 在Inside the Storage Engine: Anatomy of a Data Record中非常详细地解释了记录的内部结构。


小智 10

我测试了这个案例。您可以使用以下步骤更快地完成此操作:

  1. 使用不同的名称创建相同的表结构(称为 Tbl2)
  2. 更改 Tbl2 上的列
  3. 将数据从 Tbl1 插入到 Tbl2
  4. Drop Tbl1(旧表)
  5. 将 Tbl2(新的)重命名为 Tbl1

这将为您提供更好的性能。

原因是,更改包含数据的表上的列,将需要大量的数据传输和数据页对齐。使用我的解决方案,您只需插入数据而无需任何页面重组。

编辑:
在我的测试中,我使用了大约 40 M 行的表,表大小为 7 GB,索引大小为 2.5 GB。当我使用重命名原始表中的字段时,建议的方法是 1 分钟 VS 4 分钟