locking升级 – 这里发生了什么?

在SQL Server 2008中更改表(删除列)时,我单击了“生成更改脚本”button,我注意到它生成的更改脚本会删除列,并显示“go”,然后运行额外的ALTER TABLE语句表的锁升级为“TABLE”。 例:

ALTER TABLE dbo.Contract SET (LOCK_ESCALATION = TABLE) 

我也应该注意到,这是改变脚本正在做的最后一件事情。 这里做了什么,为什么将LOCK_ESCALATION设置为TABLE?

“ locking升级 ”是SQL如何处理大型更新的locking。 当SQL要改变很多行的时候,数据库引擎会更有效率地使用更less的更大的锁(例如整个表),而不是locking许多较小的事物(例如行锁)。

但是,当您拥有一个巨大的表时,这可能会有问题,因为对整个表进行locking可能会长时间locking其他查询。 这是一个折衷:许多小粒度的锁比粗粒度锁less一些(或一个),并且有多个查询locking表的不同部分,如果一个进程在另一个进程上等待,则会造成死锁的可能性。

在SQL 2008中有一个表级选项LOCK_ESCALATION ,它允许控制锁升级。 默认的“TABLE”允许锁升级到表级。 在大多数情况下,DISABLE防止锁升级到整个表。 除非表被分区,否则AUTO允许表锁,在这种情况下,锁只能分配到分区级别。 看到这个博客文章了解更多信息。

我怀疑IDE在重新创build表时添加了这个设置,因为TABLE是SQL 2008中的默认值。请注意,SQL 2005中不支持LOCK_ESCALATION,所以如果尝试运行脚本2005实例。 另外,由于TABLE是默认值,因此在重新运行脚本时可以安全地删除该行。

还要注意的是,在SQL 2005之前,在这个设置出现之前,所有的锁都可以升级到表级 – 换句话说,“TABLE”是SQL 2005中唯一的设置。

您可以通过在运行脚本主要部分之前和之后比较此值来检查是否需要在脚本中包含LOCK_ESCALATION语句:

 SELECT lock_escalation_desc FROM sys.tables WHERE name='yourtablename' 

在我的情况下,改变表删除或添加约束似乎并没有修改这个值。