我正在尝试诊断一个间歇性需要很长时间的查询。我怀疑它可能在尝试获取锁时被阻止。我无权在遇到问题的环境中使用探查器。
有什么方法可以让我在不使用外部分析器的情况下获取有关此单个查询被阻止多长时间的统计信息?
我有一个非常基本的表:
CREATE TABLE [obj_local] (
[obj_id] INT NOT NULL,
[value] NVARCHAR (1000) NOT NULL
);
Run Code Online (Sandbox Code Playgroud)
这个表存储了很多数据,我需要在value
列中搜索一个字符序列:
SELECT [obj_id] FROM [obj_local] WHERE [value] LIKE '%{substring}%'
Run Code Online (Sandbox Code Playgroud)
这是非常缓慢的。我的理解是,由于两边的通配符,索引对我没有帮助,全文索引也对我没有帮助,因为我不是在搜索标记(单词)。
我可以做些什么来优化此搜索?
我正在调查由两个并发 UPDATE 语句引起的死锁:
UPDATE [table]
SET [column] = 0
WHERE [unindexed_column] = @id
Run Code Online (Sandbox Code Playgroud)
我的理解是,因为WHERE
预测的列是未索引的,所以执行了全表扫描。对于每一行,获取一个更新锁。如果它与WHERE
子句匹配,则它升级到排他锁并保持它直到语句完成。
当会话 A 拥有第 2 行的排他锁并试图获取第 1 行的更新锁,而会话 B 拥有第 1 行的排他锁并试图获取第 2 行的更新锁时,就会发生死锁。
死锁的原因是有道理的,但我不完全理解如何执行表扫描使这种情况成为可能。如果两个查询以相同的顺序执行扫描,最坏的情况似乎是其中一个查询在获取更新锁时被阻塞,直到另一个查询完成并释放它的锁。
表扫描是如何执行的?表格行的扫描顺序是否不一致?如果更新语句未能获得更新锁,它是否会转到下一行并稍后再次尝试上一行?究竟是什么让这种僵局成为可能?