在生产数据库中添加可空列花费了太多时间

我正在运行的生产数据库通常每分钟有50-100个插入操作。我正在尝试使用以下方法在生产数据库中添加一个新列:
ALTER TABLE MyDB ADD [MyColumn] varchar(30)
GO
这个查询一直在运行,直到我停止它为止。还能做些什么?
1个回答

像这样添加一个可空列通常是一个仅元数据操作。只要它能在短时间内获取表的模式稳定锁来添加列,它就会几乎立即完成。

如果你发现它花费了很长时间,原因很可能是其他会话正在阻塞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
请注意,将数据库设置为单用户模式可能会导致正在进行的事务被回滚,这可能会导致数据丢失,具体取决于客户端软件的设计方式。在执行ALTER DATABASE语句时,任何正在进行的事务都需要在将数据库切换回多用户模式后重新执行。请查看Microsoft Docs页面上关于ALTER DATABASE的内容,特别是关于WITH ROLLBACK的部分,了解控制服务器将数据库设置为单用户模式的各种选项。