如果我在 SQL Server 表中添加或删除列,我认为我会出现页面拆分或空白。由于行的大小已更改。
当我使用 RedGate SQL Compare 创建转换脚本时,它的策略是创建一个临时表,将所有数据复制到该表中,删除旧表,然后重命名临时表。
我假设这会清理页面,因为所有行都是“完美”顺序插入的。
我最近有一位 DBA 告诉我,这种“复制并重命名”的方法效率低下、成本高昂且没有必要。
这两种方法的优点是什么?
如果我在 SQL Server 表中添加或删除列,我认为我会出现页面拆分或空白。由于行的大小已更改。
当我使用 RedGate SQL Compare 创建转换脚本时,它的策略是创建一个临时表,将所有数据复制到该表中,删除旧表,然后重命名临时表。
我假设这会清理页面,因为所有行都是“完美”顺序插入的。
我最近有一位 DBA 告诉我,这种“复制并重命名”的方法效率低下、成本高昂且没有必要。
这两种方法的优点是什么?
我建议您阅读底层的 SQL Server 表列。您会看到许多列 DDL 操作会导致表中出现“幻影”列,即存在于表中但用户不可见的物理列。重建将删除所有这些幽灵列。
大多数情况下这是良性的,但有些暗区可能会导致KB2504090中描述的问题:
我个人避开了所有模式比较工具和基于比较差异的部署/升级。关于更改架构,根本没有放之四海而皆准的正确方法。就像 Henrik 提到的那样,我已经被 500GB 的表“复制”、tyvm 烧毁了,对我来说不再有差异。相反,我建议迁移,编码为 SQL 脚本并在部署之前对相关数据大小进行测试。请参阅版本控制和您的数据库。Rails ActiveRecord Migrations确实理解了这一点。
如果您的更改只是元数据更改,则不会触及表中的所有行,也不会发生页面拆分。如在
如果它不仅仅是元数据更改,(如
),那么你的聚集索引的重建将在引擎盖下进行“复制和重命名”。
我们的一些表有 150 亿行,重建聚集索引需要 15-20 个小时。当我无法接受等待重建的 20 小时停机时间时,我使用“复制并重命名”方法。首先,我复制了 149.9 亿行,然后我禁用了插入行的作业,将剩余的 1000 万行带到新结构中,最后重命名。
是的,这有点贵(占用我的时间),但系统会尽可能长时间保持在线状态。
你像这样重建一个索引:
这可以编写脚本,因此比“复制和重命名”容易得多。