2

我在 MSSQL 服务器 2005 上有一个大约 100 列、大约 30M 行的表。

我需要更改 2 列 - 将它们的类型从 VARCHAR(1024) 更改为 VARCHAR(max)。这些列上没有索引。

我担心这样做会填满日志,并导致操作失败。如何估计此类操作所需的可用磁盘空间(包括数据和日志)以确保它不会失败?

4

4 回答 4

1

你是对的,增加列大小(包括到 MAX)将为一个大表生成一个巨大的日志,因为每一行都会被更新(在场景后面,旧列被删除,新列被添加并复制数据)。

  1. 添加一个类型为 的新列VARCHAR(MAX) NULL。作为可为空的列,将仅作为元数据添加(无数据更新)
  2. 将旧列中的数据复制到新列。这可以分批完成,以减轻日志压力。
  3. 删除旧列。这将是仅元数据操作。
  4. 用于sp_rename将新列重命名为旧列名。
  5. 稍后,在您方便的时候,重建聚集索引(如果需要,在线)以摆脱旧列占用的空间

这样,您可以通过在步骤 2) 中控制批次来控制日志。您还可以通过不将整个表复制到新表中来最大限度地减少对权限、约束和关系的破坏(因为 SSMS 做得很糟糕......)。

您可以一次对两列执行此序列。

于 2010-11-03T21:52:29.553 回答
1

为什么增加 VARCHAR 限制会填满日志?

于 2010-11-03T21:27:30.807 回答
1

我建议您考虑:

  1. 使用新架构创建一个新表
  2. 将旧表中的数据复制到新表中
  3. 丢弃旧表
  4. 将新表重命名为旧表的名称

这可能是一个成本低得多的操作,并且可以使用 INSERT/SELECT 以最少的日志记录来完成(如果这是 SQL Server 2008 或更高版本)。

于 2010-11-03T21:21:49.730 回答
0

尝试以较小的部分进行一些测试。我的意思是,您可以在本地创建具有几千行的相同结构,并查看前后的差异。我认为这种变化将是线性的。真正的问题是关于重做日志,它是否适合它,因为你可以立即完成它。一定要在网上做,还是可以暂时停产?如果可以停止,也许有一种方法可以像在 Oracle 中一样停止 MSSQL 中的重做日志。它可以使它更快。如果您需要在线进行,您可以尝试创建一个新列,将值按循环复制到其中,例如一次 100000 行,提交,继续。完成后可能删除原始列并重命名新列比更改更快。

于 2010-11-03T21:33:23.100 回答