将可空列添加到生产数据库需要太多时间

use*_*567 6 sql-server sql-server-2014

我正在运行生产数据库,通常每分钟有 50-100 个插入。我正在尝试使用以下方法在生产数据库中添加一个新列,

ALTER TABLE MyDB ADD [MyColumn] varchar(30)
GO
Run Code Online (Sandbox Code Playgroud)

这个查询一直在运行,直到我停止它才完成。我还能做什么?

Han*_*non 17

添加像这样的可为空的列通常是元数据操作。也就是说,只要它可以在添加列所需的短时间内获得表上的模式稳定性锁定,它就会几乎立即完成。

如果您看到它需要很长时间,原因很可能是其他会话阻止了该ALTER TABLE语句。ALTER TABLE还要意识到,当您运行该语句时,在它等待获取模式稳定性锁时,它将阻塞对该表的后续查询。您可能希望在运行语句之前查看为会话设置锁定超时ALTER TABLE

如果阻止其他会话有问题,您可以等到活动减少一段时间,然后运行命令。或者,您可以将数据库置于单用户模式,更改表,然后将其放回多用户模式 ​​- 当然这会阻止任何会话在此期间访问数据库。

要将数据库置于单用户模式并更改表,您需要执行类似以下操作:

USE master;

ALTER DATABASE [MyDB] 
SET SINGLE_USER 
WITH ROLLBACK IMMEDIATE;
GO

USE [MyDB];
ALTER TABLE [MyDB] ADD [MyColumn] varchar(30) NULL;
GO

USE [master];
ALTER DATABASE [MyDB]
SET MULTI_USER;
GO
Run Code Online (Sandbox Code Playgroud)

但请注意,将数据库设置为这样的单用户模式将导致任何正在进行的事务回滚,这取决于您的客户端软件的设计方式,可能会导致数据丢失。ALTER DATABASE一旦数据库恢复到多用户模式,任何在执行语句时进行中的事务都需要重新执行。查看ALTER DATABASE的 Microsoft Docs 页面,特别是有关WITH ROLLBACK控制服务器如何将数据库置于单用户模式的各种选项的部分。