【发布时间】:2013-02-19 17:47:29
【问题描述】:
我有两个非常相似的查询:
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 Key Lookup (Clustered).. cost: 67%
【问题讨论】:
-
基础表的原生排序顺序是什么?如果是 asc,则 desc 查询将需要先构建整个结果集,然后才能对其进行 desc 排序。
-
explain plan或execution plan:你可以在那里查看.. -
@MarcB 什么是“基础表的本机排序顺序”?您是指聚集索引的键吗?
-
您的前两个示例不是存储过程,它们只是参数化查询。它们仍然可以有一个缓存的执行计划,但它们不是存储过程。
-
好的,所以第二个参数化查询执行时间很长,而简单的选择语句非常快。
标签: sql sql-server-2008