我有一张频繁读取,插入和放大的表格。更新(它包含网站用户的会话数据)。它在varchar
字段上有一个名为sessionID
的聚簇索引。
我需要根据另一个表中的sessionID
列表删除一堆记录。当我尝试一次删除大量的时,会创建一个锁,以防止写入和读取表。
如果我使用SSIS包中的foreach循环逐行删除它们,它似乎消除了锁定。
逐行删除是否会产生长期的负面影响?
答案 0 :(得分:1)
好的,这是关于制表锁,页锁和行锁的问题。发生的事情是你从多个页面删除所以sql锁定整个表。 Sql通常每个事务使用一个锁,因此它将选择覆盖受影响的所有行的最小锁。删除一行,它将使用一个rowlock,删除多个连续记录,它可以使用页面锁定,从多个页面中删除记录,它将锁定整个表格。
使用varchar作为PK和聚簇索引,您不太可能遇到页锁定,因为记录在表中出现的顺序是随机的(更多的是为什么在一分钟内这是非常不受欢迎的)。所以你的选择是行锁或标签锁,因为锁定表不是一个选项,行锁是你唯一的选择。
至于不良影响,drcopypaste提到了事务日志问题,但如果你的PK /集群不是顺序的,那么会出现更糟糕的问题。如果每次插入记录或删除记录时它都不是顺序的,则DB必须移动所有后续记录,因为聚簇索引(几乎总是在表pk上)是行在表上的物理排序方式