SQL Server 2014 标准版
在我的情况下,我有一个巨大的表(超过 1 亿行),需要:
- 向其添加列
- 在该列中设置默认值
我在 https://technet.microsoft.com/en-us/library/ms190273(v=sql.110).aspx 中看到有一个新的 lock_escalation 选项。
例如,这是否允许我在没有表锁的情况下执行以下操作:
例如
ALTER TABLE Protocols set (LOCK_ESCALATION = DISABLE);
go
ALTER TABLE Protocols
ADD ProtocolTypeID int NOT NULL DEFAULT(1)
GO
然而,令人担忧的是:
a) LOCK_ESCALATION = DISABLE -- 它到底是做什么用的,它在这里适用吗?(SQL Server 文档有点薄......也许它只适用于分区表?)
b) LOCK_ESCALATION = DISABLE 会影响事务大小吗?(看起来它仍然会产生一笔巨大的交易?)
c) LOCK_ESCALATION = DISABLE 是否会应用并避免表锁?
d) 有没有办法把它分块?(无法想象,但在较新的 SQL 版本中有这么多新的魔法......我应该问!)
你说文档很薄,但答案都在那里。
锁升级
您确实需要阅读整个页面,但本质上锁升级仅适用于“常规”锁(例如共享锁、独占锁)。更改对象结构的操作采用限制性更强的模式锁(例如 Sch-M),这会阻止对被修改对象的所有并发访问。因此,不需要限制较少的“普通”锁。最终,您提出的问题是没有实际意义的,因为
ALTER TABLE
不采用可能升级为分区或对象级锁的行或页级锁。关于
ALTER_TABLE
(在备注部分):和:
如果您使用的是企业版,您建议的更改可能是即时的,仅更改元数据(当然,对新列中数据的任何后续更改都需要实际分配、数据移动和日志记录)。
实际上,添加此列将是一项昂贵的、长时间运行的、完全记录的、单一事务的、数据大小的操作。如果不更改列的定义,就无法“分块”此更改(可以将可为空的列添加为仅元数据更改,然后以块的形式更新)。