【发布时间】:2016-10-10 14:18:25
【问题描述】:
我有一个名为 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 rows) 启动并锁定表几分钟,阻止所有较小的进程完成。
我想这是因为第一个尝试插入表的进程正在获取 TABLE LOCK,所以我使用以下命令禁用了锁升级:
ALTER TABLE MyFactTable SET (LOCK_ESCALATION=DISABLE)
这确实解决了问题,但现在我想知道这样做的后果可能是什么。
有没有人遇到过这样的情况并愿意分享他们的经验。
另外,我还可以采用哪些其他可能的解决方案?我考虑过对表进行分区并将所有小运行放在一个分区中,将所有大运行放在另一个分区中(我不在乎大运行是否会自己阻塞,我只是想确保小运行不会被大的)。 你怎么看?
我想值得一提的是,该表永远不会更新,并且一旦插入 RunID,它只会被查询(因此不再使用相同的 RunID 插入),最终会被清理过程删除。
谢谢, 迭戈
【问题讨论】:
-
它带有资源成本。锁升级的整个过程就是把多条记录锁所需的资源节省下来,全部增加到一个表锁。
标签: sql sql-server locking sql-server-2014