所以这很奇怪。这是我的代码:
PRINT 'Define cursor'
DECLARE cursor1 CURSOR FOR
SELECT b.EmploymentTypeID
FROM EmploymentTypes b INNER JOIN #ListEmployments l
on b.EmploymentID = l.EmploymentID
PRINT 'Open cursor'
OPEN cursor1
FETCH NEXT FROM cursor1 INTO @pEmploymentTypeID
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT '1) Inside WHILE loop. @pEmploymentTypeID: ' + convert(varchar(20), @pEmploymentTypeID)
PRINT '2) Inside WHILE loop. @@FETCH_STATUS: ' + convert(varchar(20), @@FETCH_STATUS)
-- do some work
UPDATE EmploymentTypes
SET EmploymentTypeRD = EmploymentTypeID
WHERE EmploymentTypeID = @pEmploymentTypeID
AND EmploymentTypeRD = 0
PRINT '3) Inside WHILE loop. …
Run Code Online (Sandbox Code Playgroud) 我有一个 SQL Server 数据库,偶然发现了一个表,其中包含一个名为 ActivityId 的唯一标识符主键,以及 StateCode (int) 和 ActivityTypeCode (int) 列以及许多其他列。这些表有 13M 行,ActivityTypeCode 有 94 个唯一值,行数从 1 到 4M。好的,这是奇怪的部分:我在 (StateCode, ActivityId) 上有 97 个不同的过滤索引,其中唯一的区别是 (ActivityTypeCode=( _some_value_ ))上的 where 子句。
在我看来,所有 97 个索引都可以删除并替换为仅 StateCode 上的一个索引(因为 ActivityID 是主键并且已经作为隐藏列包含在内)。我的问题是:有什么理由要保留多个过滤索引吗?他们能以某种方式减少死锁吗?我已经进行了一些测试,我认为没有任何理由拥有如此多的索引。想法?
肯
[编辑] 基于下面的优秀答案,我做了一些测试,似乎过滤后的索引不会阻止简单查询的阻塞。我的索引是以下形式:
CREATE INDEX IX_StateCode_ActivityID_ActivityTypeCode_Filtered_0 ON dbo.Activities(StateCode,ActivityId) WHERE ActivityTypeCode = 0;
Run Code Online (Sandbox Code Playgroud)
如果我进入一个数据库连接并发出以下命令:
Begin transaction;
Update Activities set StateCode=888 where ActivityTypeCode=1
Run Code Online (Sandbox Code Playgroud)
然后进入第二个连接并发出以下命令:
Update Activities set StateCode=999 where ActivityTypeCode=3
Run Code Online (Sandbox Code Playgroud)
第二个连接挂起。似乎这些不同的索引并不能阻止阻塞,所以我看不出有任何理由保留它们。鉴于存在不存在的 ActivityTypeCode 值的索引,我怀疑它们都是由某种开发工具生成的。仅供参考:这是来自第三方供应商。
感谢大家的帮助。
[编辑 #2] 经过详细检查,并非所有索引都相同。下面是组合。请记住,ActivityID 是主键。
StateCode, ActivityID
StateCode, CreatedOn, ActivityID
StateCode, CreatedOn, …
Run Code Online (Sandbox Code Playgroud)