微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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的进程.从那里你可以决定是否采取适当的行动来杀死违规进程,或者只是等待.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐