【发布时间】:2016-04-20 14:40:06
【问题描述】:
在数据库 A 表中频繁发生 SELECT、UPDATE、BULK INSERTS 并且发生严重阻塞,并且每次 BULK INSERT 被选为死锁牺牲品时,我们都会因为 BULK INSERT 失败而丢失一些数据。
SELECT 阻止 BULK INSERT 或 UPDATE 每次都阻止 BULK INSERT,反之亦然,所有这些语句(查询)都来自应用程序。我们没有使用任何存储过程(不幸的是我们不能使用存储过程)
数据库快照是 READ Committed,简单的恢复模型,正确索引并且没有发现碎片。统计数据是最新的,正确设置了 MAXDOP,针对临时工作负载进行优化 = 1,AUTO_UPDATE_STATISTICS_ASYNC ON,mdf 和 ldf 的自动增长为 500mb,mdf 和 ldf 的 tempdb 自动增长为 500mb ..btw,所有数据库都在同一个磁盘。内存为 6GB。数据库总大小(如果为 60GB)。 SQL Server 2012 标准版。 PageFile.Sys 为 9.8GB。等待统计是 LCK_M_IX(59%),PAGEIOLATCH_SH(25%)
我想知道,有没有办法解决这个问题?
有没有办法强制来自应用程序(查询计划)的代码在 SELECT 上使用 NO LOCK?或以任何方式强制任何查询或任何登录 xyz 应用程序使用 NO LOCK?
将 ISOLATION LEVEL 更改为 READ UNCOMMITTED 有帮助吗?
将死锁优先级设置为 LOW?
【问题讨论】:
-
这对SO来说是一个很大的话题,但是你有没有仔细研究过,为什么会死锁?选择是读取表的大部分还是整个表被锁定?
-
...你在期待什么?
BULK INSERT
旨在单独运行,或与其他BULK INSERT
语句同时运行。它绝对不会与同一张桌子上的其他语句配合得很好。你可以在临时表中BULK INSERT
代替,然后从那里做一个常规的INSERT
吗? -
您能否将您的一些工作负载更改为更小的批次?我确信有更优雅的解决方案,但这可以提供一些暂时的缓解,这意味着您不必重新启动整个批量插入。
-
JamesZ:选择读取表格的大部分 -- 是
-
Jeroen:你能不能在临时表中批量插入,然后从那里进行常规插入——所有代码都是从应用程序调用的,我无法控制。
标签: sql sql-server