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的进程.从那里你可以决定是否采取适当的行动来杀死违规进程,或者只是等待. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |