我们有一个 SQL Server 2008 数据库,其中一个表包含超过 14 亿条记录。由于坐标系的调整,我们必须将坐标列的数据类型从 decimal(18, 2)
扩展为 decimal(18, 3)
。
我们尝试了多种方法,但在执行大约 14 小时后,所有方法都导致异常(事务日志已满)。
这些是我们尝试过的事情:
更改表
ALTER TABLE Adress ALTER COLUMN Coordinate decimal(18, 3) NULL
设计师
- 取消选中
工具 > 选项 > 设计器 > 防止保存需要重新创建表的更改
- 开放设计器
- 将列的数据类型更改为
decimal(18, 3)
右键单击 > 生成更改脚本...
- 取消选中
此脚本的作用是使用新数据类型创建一个新表,将旧数据复制到新表,删除旧表并重命名新表。
不幸的是,这两次尝试都会在执行 14 小时后导致事务日志已满异常。
我想,通过ALTER TABLE...ALTER COLUMN...
更改数据类型只是更改元数据,应该在(毫秒)秒内完成?
- 您知道我可以尝试其他方法吗?
- 为什么我的尝试(尤其是#1)需要那么多时间?
提前致谢
最佳答案
主要问题是表中保存了大量数据。你的两次尝试看起来也不错。我必须说,由于数据很大,它们都肯定需要时间。
每次更改列数据类型时,SQL SERVER 都会尝试将现有数据转换为目标数据类型。处理大量数据的转换可能会导致执行延迟。
此外,我想知道您是否有任何触发器在 table 上。?
嗯!最后我建议您遵循以下步骤。至少尝试一下
- 删除指向旧列的所有主键/索引/约束,并禁用任何触发器(如果有)。
- 引入具有新数据类型的新可空列(即使 它应该是 NOT NULL)到表中。
- 现在对表进行更新查询,将新列值设置为旧列值。您可以在更新 1000/100000 批记录时进行分块更新。您还可以对查询应用条件以获得更好的结果。
- 通过将新列值设置为旧列来更新所有表后,请从设计器中将 NULL 字符删除为 NOT NULL(如果它是 NOT NULL) )。
- 删除/删除旧列。执行选择查询并验证您的更改。
我要补充的最后一点是您的数据库事务日志也已满,可以缩小,但需要采取一些预防措施。 Here这是如何重置事务日志的一个很好的例子。也应该看看这个。
希望这有帮助。 :)
关于sql-server - 更改 SQL Server 中列的数据类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37938855/