sql – 为什么在现有列中添加可空的默认约束需要很长时间?

前端之家收集整理的这篇文章主要介绍了sql – 为什么在现有列中添加可空的默认约束需要很长时间?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个现有的表约有4亿行.该表包含一组名为IsModified,IsDeleted和IsExpired的位列.
CREATE TABLE [dbo].[ActivityAccumulator](
    [ActivityAccumulator_SK] [int] IDENTITY(1,1) NOT NULL,[ActivityAccumulatorPK1] [int] NULL,[UserPK1] [int] NULL,[Data] [varchar](510) NULL,[CoursePK1] [int] NULL,[TimeStamp] [datetime] NULL,[SessionID] [int] NULL,[Status] [varchar](50) NULL,[EventType] [varchar](40) NULL,[DWCreated] [datetime] NULL,[DWModified] [datetime] NULL,[IsModified] [bit] NULL,[DWDeleted] [datetime] NULL,[IsDeleted] [bit] NULL,[ActivityAccumulatorKey] [bigint] NULL,[ContentPK1] [bigint] NULL
) ON [PRIMARY]

我想为表添加一个默认约束,对于所有未来插入的行,将这些位列默认为0.我试图通过以下命令执行此操作:

ALTER TABLE ActivityAccumulator 
ADD CONSTRAINT DF_ActivityAccumulatorIsExpired DEFAULT (0) FOR IsExpired

ALTER TABLE ActivityAccumulator 
ADD CONSTRAINT DF_ActivityAccumulatorIsDeleted DEFAULT (0) FOR IsDeleted

ALTER TABLE ActivityAccumulator 
ADD CONSTRAINT DF_ActivityAccumulatorIsModified DEFAULT (0) FOR IsModified

我最终想回去清理现有的数据,将零值放在有NULL值的地方,但现在我并不需要这样做.

只是尝试运行第一个ADD CONSTRAINT命令已经执行了一个多小时.鉴于我不想改变任何现有的价值观,为什么这么长时间?

解决方法

一种可能性是您的服务器上有另一个进程锁定此表.

想像一下,我打开了两个SSMS窗口,第一个执行这些命令:

-- Session 1
CREATE TABLE Foo(IsTrue BIT) 
INSERT INTO Foo VALUES (1),(1),(0)
BEGIN TRANSACTION
UPDATE Foo SET IsTrue = 1 - IsTrue

然后将SSMS窗口打开,使事务永远不会关闭,尝试在其他SSMS会话中执行此简单约束命令将永久挂起:

-- Session 2
ALTER TABLE Foo ADD CONSTRAINT FooDefault DEFAULT(0) FOR IsTrue

请注意,在此示例中,表的大小或复杂性是无关紧要的;我被迫等待交易完成.在我通过提交交易或关闭会话1释放Foo上的锁之后,会话2中的alter指令将不会完成.

你怎么知道这是你的问题?看看SSMS活动监视器中的“进程”列表.如果您的ALTER指令正在等待其他任务完成,“阻止”列中将显示一个数字,表示导致您的问题的命令的会话ID.

那个会议可能会等待另一个等等.如果您遵循这些引用,您最终会在“Head Blocker”列中找到一个具有1的进程.从那里你可以决定是否采取适当的行动来杀死违规进程,或者只是等待.

猜你在找的MsSQL相关文章