我有一个大约有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](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
命令已经执行了一个多小时了。鉴于我不想改变任何现有的价值,为什么这需要这么长时间呢?
答案 0 :(得分:5)
一种可能是您的服务器上有另一个锁定此表的进程。
想象一下,我打开了两个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
请注意,在此示例中,表的大小或复杂性无关紧要;我被迫等待交易完成。我在会话2中的alter指令不会完成,直到Foo
通过COMMIT
交易或结束会话1释放ALTER
锁定。
你怎么知道这是不是你的问题?看看"流程" SSMS活动监视器中的列表。如果您的1
指令正在等待其他内容完成,那么" Blocked By"列,指示导致问题的命令的会话ID。
那个会话可能会等待另一个会议等等。如果您遵循这些参考,您最终会在" Head Blocker"中找到一个{{1}}的流程。柱。从那里你可以决定是否采取适当的行动来消除违规过程,或者只是等待它。
答案 1 :(得分:0)
如果你想优化,重新索引和避免像Dan提到的那样的冲突,这种方式是最快的