改变表中的2列 - 冒险操作?

时间:2010-11-03 21:17:14

标签: sql sql-server-2005 alter-table

我在MSSQL server 2005上有一个包含~100列,大约约30M行的表。

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

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

4 个答案:

答案 0 :(得分:1)

我建议你考虑一下:

  1. 使用新架构创建新表
  2. 将数据从旧表复制到新表
  3. 放弃旧桌子
  4. 将新表重命名为旧表的名称
  5. 这可能是一个成本低得多的操作,并且可以使用INSERT / SELECT进行最少的日志记录(如果这是SQL Server 2008或更高版本)。

答案 1 :(得分:1)

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

答案 2 :(得分:1)

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

  1. 添加VARCHAR(MAX) NULL类型的新列。作为可空列,将仅作为元数据添加(无数据更新)
  2. 将旧列中的数据复制到新列。这可以分批进行,以减轻对数压力。
  3. 删除旧列。这将是仅元数据操作。
  4. 使用sp_rename将新列重命名为旧列名称。
  5. 稍后,在您方便的时候,重建聚集索引(如果需要,在线)以摆脱旧列占用的空间
  6. 这样,您可以通过在步骤2中控制批次来控制日志。您还可以通过不将整个表复制到新表中来最小化对权限,约束和关系的中断(因为SSMS如此糟糕......)。

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

答案 3 :(得分:0)

尝试以较小的碎片进行一些测试。我的意思是,您可以在本地创建相同的结构,只有几千行,并查看之前和之后的差异。我认为这种变化将是线性的。真正的问题是关于重做日志,如果它适合它,因为你可以立即执行它。你必须在网上做,或者你可以停止生产一段时间?如果你可以停下来,也许有办法在Oracle中停止重做日志,就像在Oracle中一样。它可以使它快得多。如果您需要在线完成,可以尝试创建一个新列,将值复制一个循环,例如一次100000行,提交,继续。完成后可能删除原始列并重命名新列比更改更快。