SQL 服务器 - 为什么更改 Table 添加可空列到 Table 导致重建

SQL Server - Why Alter Table Adding Nullable Columns to a Table causes a Rebuild

我们有一个 250GB 的数据库,其中包含一个 180GB Table(5500 万行或 550 列),我们通过以下方式向其添加 24 个新的空白列;

ALTER TABLE [Rpt].[tblHoldings]      
ADD 
    [Rating01AgencyCode] VARCHAR (50) NULL,          
    [Rating01TypeCode]   VARCHAR (50) NULL,          
    [Rating01Code]       VARCHAR (50) NULL,          
    [Rating01Score]      FLOAT (53)   NULL,          
    [Rating02AgencyCode] VARCHAR (50) NULL,          
    [Rating02TypeCode]   VARCHAR (50) NULL,          
    [Rating02Code]       VARCHAR (50) NULL,          
    [Rating02Score]      FLOAT (53)   NULL,          
    [Rating03AgencyCode] VARCHAR (50) NULL,          
    [Rating03TypeCode]   VARCHAR (50) NULL,          
    [Rating03Code]       VARCHAR (50) NULL,          
    [Rating03Score]      FLOAT (53)   NULL,          
    [Rating04AgencyCode] VARCHAR (50) NULL,          
    [Rating04TypeCode]   VARCHAR (50) NULL,          
    [Rating04Code]       VARCHAR (50) NULL,          
    [Rating04Score]      FLOAT (53)   NULL,          
    [Rating05AgencyCode] VARCHAR (50) NULL,          
    [Rating05TypeCode]   VARCHAR (50) NULL,          
    [Rating05Code]       VARCHAR (50) NULL,          
    [Rating05Score]      FLOAT (53)   NULL,          
    [Rating06AgencyCode] VARCHAR (50) NULL,          
    [Rating06TypeCode]   VARCHAR (50) NULL,          
    [Rating06Code]       VARCHAR (50) NULL,          
    [Rating06Score]      FLOAT (53)   NULL ;

我们过去使用相同的方法为此 table 添加了 75 列,只用了几秒钟。这次在弹性 ​​Azure 池 (800 EDTU) 中,我将数据库最大大小设置为 500GB,并且 运行 out of space after 运行以上查询 6 小时.

它似乎是在后台或更多地间接重建 table(即使这是一个不涉及直接复制 table 的 TSQL 调用)- 更奇怪的是,即使如果它重建 table 为什么它比另一个需要更多 ~180 GB(即 250GB + 另一个 180GB 应该小于 500GB)

注意:这些不是具有任何默认值或上面未显示的任何其他内容的索引列

我很想知道这是否是预期的行为。在 table 的末尾添加可空列是否有任何条件会触发重建,如果是,是什么条件强制执行此操作,为什么它比原始 table 消耗更多?

如果行宽之和大于页面大小(大约 8KB),可能需要做一些工作才能使您的架构适合页面。在所有情况下,固定大小的字段(例如浮动)都需要位于页面上。 SQL 确实具有获取某些 variable-sized 字段并在某些情况下将它们放入 off-row 的功能。这也许可以解释 sizeof(data) 操作,尽管这实际上只是没有完整重现的推测。

可能发生的情况的词汇是 DDL 操作需要修改所有行才能完成操作。它不是“重建”,因为您将通过构建新索引并将所有数据移动到其中来重建索引。 SQL 确实有逻辑,只要有可能,“在线”模式操作意味着如果我们可以避免执行 sizeof(data) 操作,我们就会这样做。这包括添加未定义默认值的列(因此我们不必修改 table 中的所有现有行来为这些现有行设置新的默认值)。但是,对此有一些限制。请参考本页WITH(ONLINE=ON)语法的在线文档:

https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-table-transact-sql?view=sql-server-ver15