禁用锁定升级的弊端

时间:2016-10-10 14:18:25

标签: sql sql-server locking sql-server-2014

我有一个名为MyFactTable的表,如下所示:

Create table MyFactTable
(
RunID int,
Key2 int,
Key3 int,
Key4 int,
….
Value2 numeric,
Value3 numeric,
Value4 numeric,
….
)

它还有:

  • RunID上的非唯一聚簇索引(非唯一,因为RunID可能有数十万行与之关联);
  • 一些其他非聚集索引来帮助查询;

运行ID彼此完全隔离,通常我会在此表中插入多个进程(显然有不同的RunID)。 问题是我似乎无法并行运行插入,这意味着当进程A插入表中时,进程B也会被阻止。

在95%的情况下,这不是什么大问题,因为大多数RunID都非常小(少于50万行),他们只会锁定表几秒钟,但最终会有更大的工作(20 + Millon行)启动并锁定表几分钟,阻止所有较小的进程完成。

我想这会发生这种情况,因为尝试插入表中的第一个进程是获取TABLE LOCK,因此我使用此命令禁用了锁升级:

ALTER TABLE MyFactTable  SET (LOCK_ESCALATION=DISABLE)

这确实解决了问题,但现在我想知道这样做的后果是什么。

有没有人遇到这样的情景,愿意分享他们的经验。

关于第二个问题,我可以采用哪些其他可能的解决方案?我考虑过对表进行分区并将所有小运行放在一个分区中,并将所有大运行放在另一个分区中(我不在乎大块是否会阻塞自己,我只是想确保小块不被阻塞大的)。 你怎么看待这个?

我想值得一提的是,这个表永远不会更新,一旦插入了RunID,它只会被查询(所以不再有相同的RunID插入),最终它会被清理过程删除。

谢谢, 迭

1 个答案:

答案 0 :(得分:2)

摘要:

  

对于插入/选择我没有看到禁用锁升级的任何问题,除了一些资源使用

通常情况下,插入不会锁定表格,除非您正在执行bulk loadinginsert select ..

当您禁用锁定升级时,除了使用更多内存之外,我没有看到任何插入问题,除了更多的内存使用情况,使用的内存将是

  

Lock在SQLServer中使用96字节的内存,因此当表保存每行的行锁时,使用的内存与行数* 96字节成比例

现在,当Lock_escalation被禁用时,同一个表上的插入,更新/删除等其他事务的事务一致性。

  

没有交易不一致,因为如果锁不兼容,它们将被阻止

最后,我看到其他DML交易的性能问题。有关详细信息,请参阅下面的示例

Table1有1000页,每页有100行,总共100000行。现在当你在这个表中插入数据时。现在每行都会被锁定'X'锁定,直到事务完成。所以删除/更新有检查每一行是否可以保持锁定。早期,它可以检查更高级别的锁定

我不确定删除/更新是否会在第一次找到具有不兼容锁定的行时立即被阻止,或者它将继续检查,因为ii没有测试2008实例以进行当前测试。将发布更多详细信息