【问题标题】:SQL Server 2012 takes long time on simple alter to add NULL columnsSQL Server 2012 需要很长时间进行简单的更改以添加 NULL 列
【发布时间】:2017-01-02 15:18:40
【问题描述】:

我在 SQL Server 2012 中更改表时遇到问题,将允许 NULL 的 04 列添加到具有 340 列和大约 1.66 亿行和 01 个非聚集索引的大表需要很长时间

此问题仅在还原后特定表发生。 我正在等待执行 10 个小时,但它还没有完成,所以我必须取消它以进行更多调查。这很奇怪,因为脚本真的很简单,如下所示,我们之前已经成功完成了:

alter table sample_database.sample_schema.sample_table
add column_001 int null
   ,column_002 numeric(18,4) null
   ,column_003 nvarchar(500) null
   ,column_004 int null;

我的问题是:

  • 为什么会发生奇怪的事情?
  • 与我们的部署包有关,如何解决?我们已经完成了使用新列创建新表并加载数据的解决方法。但这对我们不起作用。
  • 以后如何预防这个问题?

非常感谢大家,

【问题讨论】:

  • 在我的情况下,添加的列允许为 NULL,因此它们不需要在具有默认值的新列上逐行更新。在您提到的线程中还有一件事,我担心删除当前索引,然后添加新列并最终重新创建索引,这是一个好的解决方案吗?因为据我了解,重新创建索引需要时间。
  • 是的,它可以提供帮助。另外,可以肯定的是,这次桌子没有使用
  • 你用的是sql 2012吧?
  • 尝试将您的代码放入事务中

标签: sql sql-server tsql sql-server-2012 alter-table


【解决方案1】:

如果是2012年(根据tag),可能会出现这种情况:

http://rusanu.com/2012/02/16/adding-a-nullable-column-can-update-the-entire-table/

如果在 SQL Server 2012 中添加可为空的列有可能 将行大小增加到 8060 大小,然后 ALTER 执行 对表的每一行进行离线数据大小更新,以确保它 适合页面。此行为是 SQL Server 2012 中的新增功能。

【讨论】:

  • 。 .即使更新每一行也不能解释为什么查询需要 10 hours 。 . .或更多。
  • 该更新操作可能涉及大量的页面拆分和指针转发。 166M行340列,未知配置(vm/cloud、trans log increment、io、其他db和non-db活动等),可能会发生
  • “此行为是 SQL Server 2012 中的新行为。”这与 SQL Server 2012 有关。我们如何克服和防止这种情况?
  • @Anton 对于文章中的例子,它与固定长度字符有关,但在我的例子中,我们也使用 nvarchar。
  • 您正在添加具有 int 和 numeric 数据类型的固定长度列,足以触发上述行为。计算所有行的行大小以确认它...您的列太多,通常这是由于设计不当造成的。考虑创建更多具有一对一关系的表,将一些数据移动到这些新表中,并更改所有相关代码。
【解决方案2】:

@Anton 解释了这背后的原因。 -分页

对于解决方法,您可以按照以下步骤操作:

  1. 创建空行的克隆表(例如SELECT * INTO <New table> from sample_table WHERE 0=1
  2. 在 .
  3. 中添加新列
  4. 将数据从 sample_table 复制到 .
  5. 一旦第 3 步完成,修改 sample_table 名称并将其重命名为 sample_table。

您还应该尝试添加具有NOT NULL 值的列,并在添加列后进行相应的修改。

【讨论】:

  • 您可以使用“批量插入”在表之间快速复制数据。
  • 我们仍然需要创建PK和Idx,它们也需要很多时间。我不认为通过添加 NOT NULL 值来节省时间,它应该更重
  • @JohnLe,显然索引创建或重建需要时间来执行,因为您有 166M 记录。但是通过复制数据和重命名表会减少当前表的负载。
【解决方案3】:

这个案例发生在我们的 UAT 环境中。在我们从最新的备份中再次恢复数据库后,这个问题就不会再发生了。改变在几毫秒内完成。

在我看来,自上次修复以来存在某些问题。

非常感谢大家,

【讨论】:

    猜你喜欢
    • 2015-05-12
    • 2021-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-10
    • 2017-12-08
    相关资源
    最近更新 更多