我有一个按以下方式定义的表:
CREATE TABLE [dbo].[MyTable]
(
[MyTable_ID] [int] IDENTITY(1,1) NOT NULL,
[COLUMN_WITH_DATA] [varchar](128) NOT NULL,
[COLUMN_A] [varchar](128) NULL,
[COLUMN_B] [varchar](128) NULL,
[COLUMN_C] [bit] NOT NULL
)
Run Code Online (Sandbox Code Playgroud)
和这样创建的索引:
CREATE INDEX [MyTable_Index_ABC] ON [dbo].[MyTable]
(
[COLUMN_A],
[COLUMN_B],
[COLUMN_C]
)
ON [PRIMARY]
Run Code Online (Sandbox Code Playgroud)
我运行以下查询:
SELECT TOP 1 [MyTable].*
FROM [MyTable](UPDLOCK)
WHERE
[MyTable].[COLUMN_A] IS NULL
AND [MyTable].[COLUMN_B] IS NULL
AND [MyTable].[COLUMN_C] = 0
Run Code Online (Sandbox Code Playgroud)
这背后的目标是获取第一个尚未使用的记录的 COLUMN_WITH_DATA 值,然后使用非空值更新其 COLUMN_A 和 COLUMN_B,以将其标记为已使用。
我在 MyTable 中有几百万条记录,其中大约一半都有:COULMN_A 和 COLIMN_B 不是 NULL(表明数据已经被消耗)。
在这种情况下,查询运行非常缓慢,执行计划显示索引:
MyTable_Index_ABC
Run Code Online (Sandbox Code Playgroud)
除非我使用查询提示,否则不使用,在这种情况下查询运行得更快。另一方面,如果我更新所有尚未消耗的行,那就是:
COLUMN_A IS NULL AND COLUMN_B IS NULL …
Run Code Online (Sandbox Code Playgroud)