Die*_*ego 5 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,
….
)
Run Code Online (Sandbox Code Playgroud)
它也有:
运行 ID 彼此完全隔离,通常我会将多个进程插入到此表中(显然具有不同的运行 ID)。问题是我似乎无法并行运行插入,这意味着当进程 A 插入表时,进程 B 也被阻止这样做。
在 95% 的情况下,这不是什么大问题,因为大多数 RunID 非常小(少于 50 万行),它们只会锁定表几秒钟,但最终会产生更大的工作(20+ 百万行) ) 启动并锁定表几分钟,阻止所有较小的进程完成。
我想这是因为第一个尝试插入表的进程正在获取一个表锁,所以我用这个命令禁用了锁升级:
ALTER TABLE MyFactTable SET (LOCK_ESCALATION=DISABLE)
Run Code Online (Sandbox Code Playgroud)
那确实解决了问题,但现在我想知道这样做的后果是什么。
有没有人遇到过这样的情况并愿意分享他们的经验。
其次,我可以采用哪些其他可能的解决方案?我想过对表进行分区并将所有小运行放在一个分区中,将所有大运行放在另一个分区中(我不在乎大的是否阻塞自己,我只是想确保小的不会被大的)。你怎么看?
我想值得一提的是,这个表永远不会更新,一旦插入了 RunID,它只会被查询(因此不会再插入具有相同 RunID 的内容),最终它会被清理过程删除。
谢谢,迭戈
概括:
对于插入/选择,除了某些资源使用之外,我没有看到禁用锁升级的任何问题
通常插入不会锁定表,除非你正在做bulk loading或insert select..
当您禁用锁升级时,除了使用更多内存之外,我没有看到插入有任何问题,除了更多内存使用之外,使用的内存将是
SQLServer中锁使用96字节内存,因此当表为每一行持有行锁时,所使用的内存与行数*96字节成正比
现在讨论当 Lock_escalation 禁用时其他事务的事务一致性,例如同一个表上的插入、更新/删除。
不会有事务不一致,因为如果锁不兼容,它们只会被阻止
最后,我发现其他 DML 事务的性能问题。有关更多详细信息,请参阅下面的示例
Table1 有 1000 页,每页有 100 行,总共 100000 行。现在当您向该表中插入数据时。现在每一行都将被锁定为“X”锁,直到事务完成。因此删除/更新必须检查每个row 知道它是否可以持有锁。之前,它可以检查更高级别的锁
我不确定删除/更新是否会在第一次发现具有不兼容锁的行时立即被阻止,或者它将继续检查,因为 ii 目前没有测试 2008 实例进行测试。将发布更多详细信息
| 归档时间: |
|
| 查看次数: |
3093 次 |
| 最近记录: |