在更新或插入的同时添加可为空的列

Dar*_*ryl 3 sql-server concurrency alter-table ddl

在 SQL Server 中,当向具有数百万行的实时 SQL Server 数据库添加允许空值的列时,如果插入或更新与 DDL 更新同时发生,会发生什么情况?

例如:

ALTER TABLE MyTable ADD MyColumn varchar(255) NULL;
Run Code Online (Sandbox Code Playgroud)

Sco*_*red 5

参考ALTER TABLE的文档(突出显示我的),

\n\n
\n

ALTER TABLE 中指定的更改会立即实施。如果更改需要修改表中的行,则 ALTER TABLE 会更新这些行。ALTER TABLE 获取表上的架构修改 (SCH-M) 锁,以确保在更改期间没有其他连接引用甚至表的元数据,需要非常短 SCH 的在线索引操作除外。 M锁在最后。在 ALTER TABLE\xe2\x80\xa6SWITCH 操作中,会在源表和目标表上获取锁。对表所做的修改都会被记录下来并且\n 是完全可恢复的。影响非常大的表中的所有行的更改,例如删除列或在某些版本的 SQL Server 上添加具有默认值的 NOT NULL 列,可能需要很长时间才能完成并生成许多日志记录。执行这些 ALTER TABLE 语句时应与影响多行的任何 INSERT、UPDATE 或 DELETE 语句一样小心。

\n
\n\n

此外,Paul Randal 在向表添加列的误解 中提供了一些关于添加列时会发生什么情况(以及操作可能需要多长时间)的有用信息。总结一些要点:

\n\n
    \n
  • 新列可以为空,默认值为 NULL。表\xe2\x80\x99s 元数据\n记录了新列存在但可能不在记录中的事实。这就是为什么空位图还具有该特定记录中\n列数的计数。SQL Server 可以确定记录中\n是否存在列。所以 \xe2\x80\x93 这不是\n数据大小操作 \xe2\x80\x93 添加新列时,现有表记录不会更新\n。仅当为某些其他操作更新记录时,\n记录才会更新。
  • \n
  • 新列可为空,默认值非 NULL。这取决于您\xe2\x80\x99 使用的 SQL Server 版本:

    \n\n
      \n
    • SQL Server 2012 之前:这是数据大小操作。当添加列时,\n非 NULL 默认值强制更新所有现有记录,因此空位图也将被更新。

    • \n
    • SQL Server 2012 及以上:与 NULL 默认可为空\n列的行为相同(即仅元数据操作)

    • \n
  • \n
  • 新列不可为空(显然具有非空默认值)。这是一个数据大小操作。
  • \n
\n