2013-02-19 122 views
0

之间SQL性能上的差异,我有两个非常simmilar查询:1秒是什么在ASC和DESC

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 

第一个执行,31秒另外一个,为什么?

有趣的是,如果我改变从存储过程的第二个查询到

SELECT TOP (1) [t0].[Production] 
FROM [dbo].[T_Production] AS [t0] 
WHERE [t0].[InputID] = 1161 
ORDER BY [t0].[Timestamp] 

也exectues在1秒内

,但令人惊讶的是,如果以后[时间戳]所以加空格最后一行看起来像这样ORDER BY [t0].[Timestamp] ',N'@p0 int',@p0=1161它也是非常快的。

编辑: 经过一些调查我检查实际执行计划和cos是: 选择成本:0 - >顶部成本6 - >索引扫描(非聚集)[T_Production] [_ dta_index_T_Production]花费94

所以我在[Timestamp]上以降序排列添加了新索引。花了几分钟的时间,现在查询执行速度与第一个一样快。

但是在这里我真的很困惑,我注意到现在附加索引的顺序应该是递增的,casuse我已经用descding,但创建另一个帮助?它使我困惑,所以我删除了我刚刚创建的这个索引,现在这个查询仍然像第一个一样快地执行。也许重建索引有帮助?并且这个问题将会返回。

但现在添加和删除索引后,实际执行计划是不同的: select:cost 0 - > top cost:0 - >嵌套循环(内部连接)成本0 - >索引seek(NonClustered).. 。成本33%和密钥查找(成群)..成本:67%

+0

什么是对基础表中的本地排序顺序?如果它是asc,那么desc查询将需要先构建整个结果集,然后才能对desc进行排序。 – 2013-02-19 17:48:49

+0

我该如何检查它? – kosnkov 2013-02-19 17:49:13

+0

'explain plan'或'execution plan':你可以在那里检查.. – aspiring 2013-02-19 17:49:34

回答

3

索引在关键字的列上也有ASC和DESC,这可能会对执行计划产生影响。

对于这样一个简单的查询来说,这看起来有很大的不同,但是看看索引定义和执行计划,可能必须有一个昂贵的附加排序操作。

删除索引几乎可以肯定无效缓存中的执行计划。

为了避免参数嗅探,你可以使用OPTION (RECOMPILE)与在线参数化查询或移动代码到一个存储过程,OPTIMIZE FOR UNKNOWN

+0

再次看我的问题,如果我更改存储过程到正常选择它执行速度非常快,我检查了这个查询与调整引擎,并没有找到任何可能的方式来升级。但这是真的,正常选择非常快,存储过程31秒。 – kosnkov 2013-02-19 17:53:56

+0

@kosnkov听起来好像它可能是参数嗅探,然后(存储的执行计划对于以后的执行不是最佳的)。要么使用变量屏蔽参数,要么使用OPTIMIZE FOR UNKNOWN http://www.sqlservercentral.com/blogs/practicalsqldba/2012/06/27/how-local-variable-or-optimize-for-unknown-resolve-parameter-嗅探/ – 2013-02-19 17:56:27

+0

@kosnkov另一个关于参数嗅探与使用OPTION(RECOMPILE)的内联参数化查询有关的问题:http://stackoverflow.com/questions/10933366/sp-executesql-is-slow-with-parameters – 2013-02-19 18:04:38