SELECT *
FROM dbo.Users AS u
WHERE ISNULL(u.Age, 1000) > 1000;
SELECT *
FROM dbo.Users AS u
WHERE DATEDIFF(DAY, u.CreationDate, u.LastAccessDate) > 5000
SELECT *
FROM dbo.Users AS u
WHERE u.UpVotes + u.DownVotes > 10000000
DECLARE @ThisWillHappenWithStoredProcedureParametersToo NVARCHAR(40) = N'Eggs McLaren'
SELECT *
FROM dbo.Users AS u
WHERE u.DisplayName LIKE @ThisWillHappenWithStoredProcedureParametersToo
OR @ThisWillHappenWithStoredProcedureParametersToo IS NULL;
CREATE INDEX ix_whatever ON dbo.Posts(CreationDate, Score) INCLUDE(OwnerUserId);
这个查询看起来不错:
SELECT p.OwnerUserId, p.Score
FROM dbo.Posts AS p
WHERE p.CreationDate >= '20070101'
AND p.CreationDate < '20181231'
AND p.Score >= 25000
AND 1 = (SELECT 1)
ORDER BY p.Score DESC;
该计划是一个简单的搜索...
但是因为前导键列是针对选择性较低的谓词,所以我们最终做的工作比我们应该做的要多:
表“帖子”。扫描计数 13,逻辑读取 136890
如果我们改变索引键列的顺序,我们做的工作就会少很多:
CREATE INDEX ix_whatever ON dbo.Posts(Score, CreationDate) INCLUDE(OwnerUserId);
并且阅读量明显减少:
表“帖子”。扫描计数 1,逻辑读取 5
SQL Server 正在为您创建索引
在某些情况下,SQL Server 将选择通过索引假脱机动态创建索引。当存在索引假脱机时,将不会出现丢失的索引请求。当然,自己添加索引可能是个好主意,但不要指望 SQL Server 会帮助您解决这个问题。
您可能没有丢失索引请求的原因有很多!
我们将更详细地了解其中的一些原因,并讨论该功能的一些一般限制。
一般限制
首先,来自:缺失索引功能的限制:
如本问答中所述:SQL Server 如何确定缺失索引请求中的键列顺序?,索引定义中的列顺序由 Equality vs Inequality 谓词决定,然后是表中的列序号位置。
选择性没有猜测,可能有更好的顺序可用。弄清楚这一点是你的工作。
特殊索引
缺失的索引请求也不涵盖“特殊”索引,例如:
考虑哪些列?
缺少索引键列是从用于过滤结果的列生成的,例如:
Missing Index Included 列是从查询所需的列生成的,例如:
即使经常,您排序或分组依据的列也可以作为关键列有益。这又回到了限制之一:
例如,此查询不会注册丢失的索引请求,即使在 LastAccessDate 上添加索引会阻止排序(并溢出到磁盘)的需要。
此分组查询也不针对位置。
这听起来不是很有帮助!
嗯,是的,但总比没有好。把丢失的索引请求想象成一个哭闹的婴儿。你知道有问题,但作为一个成年人,你要弄清楚那个问题是什么。
你还没有告诉我为什么我没有它们,虽然...
放松,巴科。我们快到了。
跟踪标志
如果启用TF 2330,则不会记录丢失的索引请求。要确定您是否启用了此功能,请运行以下命令:
索引重建
重建索引将清除丢失的索引请求。因此,在您开始 Hi-Ho-Silver-Away 重建每个索引之前,一旦有少量碎片潜入,请考虑每次执行此操作时要清除的信息。
您可能还想考虑为什么对索引进行碎片整理没有帮助。除非您使用的是Columnstore。
添加、删除或禁用索引
添加、删除或禁用索引将清除该表的所有缺失索引请求。如果您正在处理同一张表上的多个索引更改,请确保在进行任何更改之前将它们全部编写出来。
琐碎的计划
如果计划足够简单,索引访问选择足够明显,成本足够低,那么您将得到一个简单的计划。
这实际上意味着优化器无需做出基于成本的决策。
通过保罗怀特:
当计划微不足道时,不会探索其他优化阶段,也不会请求丢失的索引。
查看这些查询及其计划之间的区别:
第一个计划很简单,没有显示任何请求。在某些情况下,错误会阻止丢失的索引出现在查询计划中;不过,它们通常更可靠地记录在缺失的索引 DMV 中。
SARGability
即使使用索引,优化器也无法有效使用索引的谓词可能会阻止它们被记录。
通常不是 SARGable 的事情是:
例子:
这些查询都不会注册丢失的索引请求。有关这些的更多信息,请查看以下链接:
你已经有一个好的索引
拿这个指数:
CREATE INDEX ix_whatever ON dbo.Posts(CreationDate, Score) INCLUDE(OwnerUserId);
这个查询看起来不错:
该计划是一个简单的搜索...
但是因为前导键列是针对选择性较低的谓词,所以我们最终做的工作比我们应该做的要多:
如果我们改变索引键列的顺序,我们做的工作就会少很多:
CREATE INDEX ix_whatever ON dbo.Posts(Score, CreationDate) INCLUDE(OwnerUserId);
并且阅读量明显减少:
SQL Server 正在为您创建索引
在某些情况下,SQL Server 将选择通过索引假脱机动态创建索引。当存在索引假脱机时,将不会出现丢失的索引请求。当然,自己添加索引可能是个好主意,但不要指望 SQL Server 会帮助您解决这个问题。