sql - 更改大表中的列类型

标签 sql sql-server sql-server-2008 sql-server-2008-r2

我在 SQL Server 2008 R2 中有一个表,其中有接近 10 亿行。我想将两列的数据类型从 int 更改为 bigint。两次 ALTER TABLE zzz ALTER COLUMN yyy 有效,但速度非常慢。我怎样才能加快这个过程?我正在考虑将数据复制到另一个表,删除,创建,复制回来并切换到简单恢复模式,或者以某种方式使用游标一次 1000 行,但我不确定这些是否真的会带来任何改进。

最佳答案

根据您所做的更改,有时使用维护时段可能会更容易。在该窗口期间(任何人都不能更改表中的数据)您可以:

  1. 删除指向旧列的所有索引/约束,并禁用触发器
  2. 使用新数据类型添加一个新的可为空列(即使它不为空)
  3. 更新新列,将其设置为等于旧列的值(您可以在单个事务 block 中执行此操作(例如,使用 UPDATE TOP (10000) ... SET newcol = 一次影响 10000 行) oldcol WHERE newcol IS NULL)并使用 CHECKPOINT 以避免日志溢出)
  4. 更新完成后,删除旧列
  5. 重命名新列(并在适当的情况下添加 NOT NULL 约束)
  6. 重建索引并更新统计信息

这里的关键是它允许您在步骤 3 中增量执行更新,这是您无法通过单个 ALTER TABLE 命令完成的。

这假设该列在数据完整性方面没有发挥主要作用 - 如果它涉及一堆外键关系,则需要执行更多步骤。

编辑

另外,只是大声地想知道,我还没有对此进行任何测试(但将其添加到列表中)。我想知道页面+行压缩在这里是否有帮助?如果将 INT 更改为 BIGINT,则在适当压缩的情况下,SQL Server 仍应将所有值视为仍然适合 INT。同样,我还没有测试这是否会使更改更快或更慢,或者首先添加压缩需要多长时间。只是把它扔在那里。

关于sql - 更改大表中的列类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10754665/

相关文章:

php - 使用 2 个表格获取结果

sql - Hive 将字符串转换为浮点十进制

sql - 如何使用数据类型时间在 SQL Server 中插入时间

sql-server - 如何在不丢失数据的情况下更改SQL Server数据库中的列数据类型?

sql-server-2008 - 有没有工具可以将文件加载到 varbinary(max) 字段中?

sql-server - 命名管道提供程序 : Could not open a connection to SQL Server [53]

sql - 如何在 VS 2012 中使用 LocalDb 连接到较旧的 SQL 数据库?

sql - 是否可以将此 Sql 语句重构为不使用 RANK/PARTITION?

sql - 表中列的类型不能用作索引中的键列

sql - SQL Server 中的命令 LIKE '[atoz:a]%' 是什么意思?