Sql 为什么向现有列添加可为null的默认约束需要这么长时间?
我有一个大约有4亿行的现有表。该表包括一组名为IsModified、IsDeleted和IsExpired的Sql 为什么向现有列添加可为null的默认约束需要这么长时间?,sql,sql-server-2012,default-constraint,Sql,Sql Server 2012,Default Constraint,我有一个大约有4亿行的现有表。该表包括一组名为IsModified、IsDeleted和IsExpired的bit列 CREATE TABLE [dbo].[ActivityAccumulator]( [ActivityAccumulator_SK] [int] IDENTITY(1,1) NOT NULL, [ActivityAccumulatorPK1] [int] NULL, [UserPK1] [int] NULL, [Data] [varchar](51
bit
列
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
值的地方,但我现在真的不需要这样做
仅尝试运行第一个
addconstraint
命令就已经执行了一个多小时了。考虑到我没有试图更改任何现有值,为什么需要这么长时间?一种可能是服务器上有另一个进程正在锁定此表
假设我打开了两个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
请注意,在本例中,表的大小或复杂性是无关的;我被迫等待交易完成。只有通过COMMIT
关闭事务或关闭会话1释放Foo
上的锁,会话2中的alter指令才能完成
你怎么知道这是不是你的问题?查看SSMS活动监视器中的“流程”列表。如果您的ALTER
指令正在等待其他操作完成,则“阻塞者”列中会有一个数字,指示导致您出现问题的命令的会话ID
该届会议可能会依次等待另一届会议,以此类推。如果您遵循这些参考,您最终会在“Head Blocker”列中找到一个进程,该进程具有1
。从那里,您可以决定是否采取适当的行动来终止违规流程,或者只是等待它结束
如果你想优化、重新索引和避免像Dan提到的那样的冲突,这种方法是最快的。是的,对于这样的问题,我的第一个想法也是“死锁”。@Dan,+25似乎还不够。。。非常感谢。这正是问题所在。以前取消的查询仍在以终止/回滚状态运行。我非常关注所讨论的表的大小,甚至从未考虑过检查阻塞进程。大小并非完全无关:如果它是一个小表,回滚不会花费太长时间。是的。我想现在最好的办法就是等着看它能跑多久。。。不管怎样,我现在知道了我原来问题的答案。非常感谢。