【发布时间】:2016-09-21 17:32:14
【问题描述】:
我有一个表格,需要每分钟检查一次,以便在总数大于数字时发出警报。
SELECT
count(CreatedAt) Total
FROM
Process d
WHERE
d.ProcessedAt is null
AND DATEDIFF(second, GETUTCDATE(), d.CreatedAt) > 30
我的想法是创建一个过滤索引,类似于:
CREATE NONCLUSTERED INDEX [FIX_Process_CreatedAt_ProcessedAt] ON [dbo].[Process]
(
[CreatedAt] ASC
)
WHERE ProcessedAt IS NULL
但是看执行计划,有key lookup。
我不明白为什么,因为索引有两列用于查询。
谁能解释一下为什么?
【问题讨论】:
-
你的感觉是对的。这是没有意义的,不应该在逻辑上被要求。但这是一个从未修复过的优化器限制。你可以在这里投票connect.microsoft.com/SQLServer/feedback/details/454744/…
-
@MartinSmith 但这里的情况是因为 ProcessedAt 是与被索引的 CreatedAt 列不同的列,要完成该条件“d.ProccessedAt 为空”,它必须使用该值。因为该优化器必须进行键查找以获得适当的值。您提到的错误是仅当索引列和谓词列相同时..我还没有检查行为..
-
不,你错过了重点。从逻辑上讲,它根本没有必须 进行键查找来获取该列。它正在检查的条件已经由过滤的索引条件保证。对于索引中的所有行,条件都为真。从逻辑上讲,它可以像 OP 怀疑的那样简单地跳过检查它。存在查找的唯一原因是优化器当前不包含该逻辑,但可以而且应该添加它。
-
是的,你在这个例子中是正确的,我将在我的答案中添加另一个例子,如果条件发生变化,它会进行密钥查找
标签: sql-server lookup filtered-index