我在查询SQL Server2016- ADO.NET连接时收到以下错误消息
异常消息:事务(进程ID 358)在与另一个进程的lock |通信缓冲区资源上发生死锁,已被选为死锁牺牲品。重新运行交易记录。
SELECT * FROM Table2 WHERE EXISTS (
SELECT * FROM Table1
WHERE Id = '1234'
AND SourceId = Table1.[Id]);
什么可能是导致该问题的原因?
运行此查询时创建的共享/读锁定的作用域是什么?也就是说,共享锁是应用于整个Table2,还是只应用于结果集中的行?(我之所以这样问,是因为这看起来像一个相关子查询)
将其重构到内部连接会有帮助吗?
SELECT t2.* FROM Table2 t2
INNER JOIN Table1 t1
ON t2.SourceId = b.Id
WHERE t1.Id = '1234'
在日志中,当出现错误时,我没有看到任何其他更新语句更新结果集(或表) +/- 10秒。
那么,多个用户运行相同的查询会造成死锁吗?(表中没有非聚集索引)
使用索引策略加快查询速度是否有助于解决死锁情况?表有200万条记录,索引不正确(它只有一个主键(不是SourceId ))。我在执行计划中看到了索引扫描。因此,在覆盖其他列的SourceId上添加非聚集索引有帮助吗?我看到这将需要额外的400MB空间用于索引数据结构。所以理想情况下我并不想这么做。在SourceId上添加非聚集索引(不包括索引)会有帮助吗?(由于空间限制)
我们的应用程序的默认隔离级别是重复读取。使用WITH (NOLOCK)来放松隔离级别会有帮助吗?
我如何知道哪一条SQL语句与此相冲突?可以在生产数据库中运行SQL Profiler来生成DeadLock图吗?
为了识别和解决这个问题,还建议做些什么?
发布于 2019-05-31 07:30:00
降低隔离级别对锁定用户没有帮助。而是帮助其他使用锁定表的用户。将隔离级别降低为Read Uncommitted会对每个表中的No Lock语句产生相同的效果。
https://stackoverflow.com/questions/56387444
复制