我有两个非常相似的查询:
exec sp_executesql N'SELECT TOP (1) [t0].[Production]
FROM [dbo].[T_Production] AS [t0]
WHERE [t0].[InputID] = @p0
ORDER BY [t0].[Timestamp] DESC',N'@p0 int',@p0=1161
exec sp_executesql N'SELECT TOP (1) [t0].[Production]
FROM [dbo].[T_Production] AS [t0]
WHERE [t0].[InputID] = @p0
ORDER BY [t0].[Timestamp]',N'@p0 int',@p0=1161
第一个在 1 秒内执行,另一个在 31 秒内执行,为什么?
有趣的是,如果我将第二个查询从存储过程更改为
SELECT TOP (1) [t0].[Production]
FROM [dbo].[T_Production] AS [t0]
WHERE [t0].[InputID] = 1161
ORDER BY [t0].[Timestamp]
它也在 1 秒内执行
但令人惊奇的是,如果在 [Timestamp] 之后添加空格,使最后一行看起来像这样ORDER BY [t0].[Timestamp] ',N'@p0 int',@p0=1161
,它的执行速度也非常快。
编辑:经过一番调查,我检查了实际的执行计划,cos 是:select cost:0 -> top cost 6 -> index scan (NonClustered)[T_Production].[_dta_index_T_Production] cost 94
所以我在 [Timestamp] 上添加了降序的新索引。花了几分钟,现在查询的执行速度与第一个查询一样快。
但是在这里我真的很困惑,我现在注意到附加索引的顺序应该是升序的,因为我已经有了降序,但是创建另一个索引有帮助吗?它让我很困惑,所以我删除了我刚刚创建的这个索引,现在这个查询仍然像第一个查询一样快地执行。也许重建索引有帮助?这个问题将再次出现。
但是现在添加和删除索引后,实际执行计划不同:select :cost 0 -> top cost: 0 -> nested loops (inner join) cost 0 -> Index seek (NonClustered)... cost 33% and密钥查找(集群).. 成本:67%