我正在努力寻找将一些“varchar”列迁移到“nvarchar”的最佳方法。我使用的选项之一是添加新的 nvarchar 列,然后更新原始列中的值,删除原始列并将新列重命名为旧名称。
我知道它会生成大量的UNDO和REDO数据。不过,我还有其他限制(主要是 SQL Server 不支持并行 DDL 和多列 ALTER 表操作),因此让我们关注如何更快地运行更新语句。
我的 Oracle 经验告诉我使用内部并行性,但是它在 SQL Server 中可用吗?
尽管我特意将该表创建为堆表(无聚集索引),但我无法并行运行此语句。
update t
set new_col_1 = col_1
,new_col_2 = col_2
...
, new_col_N = col_N
;
Run Code Online (Sandbox Code Playgroud)
有 3 个文本列可容纳 400GB 数据。AWS RDS 的 IO 性能有限(10000 IOPS)。我们只有 4 小时的停机时间。
在此特定迁移中,不能选择在线重建,因为必须先将数据迁移(到 nvarchar),然后才能启动应用程序。在启动期间,它会检查实际数据类型是否与定义的数据类型(在应用程序元数据存储库中)相对应。
我知道碎片化,但我们别无选择。不过,如果有一些在线重建命令,它可能会很有用,因为我们稍后将能够进行迁移和碎片整理。实际上,作为准备步骤之一,我们正在删除聚集索引。稍后将再次创建该索引,我相信这将解决碎片问题,因为我们将从堆转移到 b*tree 结构。
令人非常沮丧的是我们无法使用任何其他“并行”技术。我正在考虑尝试手动并行更新,通过针对目标表的不重叠范围运行一些并行更新语句。尽管如此,锁升级可能是下一个问题,因为我将在每个更新中更新数百万条记录,并且很可能 SQL Server 将尝试升级到表锁,这将锁定其他更新,并且死机锁定将是最终结果..