2

我有一个 SQL Server 数据库,我A,B,C通过在 SQL 作业中安排的 SQL 脚本在某些条件下批量删除三个表中的行。该作业运行 2 小时,因为表中有大量数据。在作业运行时,我的前端应用程序无法访问(给出超时错误),因为应用程序在这些相同的表中插入和更新数据A,B,C

前端应用程序是否可以在 SQL 脚本运行时并行运行而不会出现任何问题?我检查了表上的锁并且 SQL Server 正在获取页锁。可以Read Committed SnapshotSnapshot隔离级别或将页锁转换为行锁在这里有所帮助。需要建议。

4

2 回答 2

2

将操作分为两个阶段。在第一阶段,收集要删除的行的主键:

create table #TempList (ID int);

insert  #TempList
select  ID
from    YourTable

在第二阶段,使用循环小批量删除这些行:

while 1=1
    begin
    delete  top (1000)
    from    YourTable
    where   ID in (select ID from #TempList)

    if @@rowcount = 0
        break
    end

较小的批次将允许您的前端应用程序在它们之间继续。

于 2014-04-23T14:26:17.717 回答
0

我怀疑 SQL Server 在某些时候会升级为表锁定,这意味着该表不可访问,无论是读取还是更新。

要在处理大型删除时优化锁定和并发性,请使用批处理。从 5000 行开始(以防止锁升级)并监控它的行为方式以及是否需要进一步调整。5000 是一个“神奇的数字”,但它足够低,锁管理器不会考虑升级到表锁,并且对于性能来说足够大。

超时是否会发生也取决于其他因素,但如果不完全消除,这肯定会减少。如果超时发生在读取操作上,您应该能够摆脱它们。当然,另一种方法是增加客户端的命令超时值。

更准确地说,快照(乐观)隔离也是一种选择READ COMMITTED SNAPSHOT,但它无助于其他会话的更新。此外,请注意版本存储(在 tempdb 中)的增长。最好将它与建议的批处理方法结合起来以保持事务较小。

此外,如果数据库正常处于完全恢复状态,请在删除期间切换到批量日志恢复。但是一旦完成就切换回来,并进行备份。

差点忘了——如果是企业版的 SQL Server,对你的表进行分区;然后您可以将分区切换出去,这几乎是瞬间的,客户永远不会注意到它。

于 2014-04-23T14:25:07.863 回答