2009-02-23 114 views
4

为什么如果我将查询作为参数化过程运行,它的运行速度会快10倍,如果直接将它作为参数化查询运行?为什么查询速度很慢但SQL Server上的过程很快?

我在两种情况下都使用完全相同的查询,并且无论是从Management Studio调用还是从代码中调用SqlCommand都无关紧要。

编辑:执行计划看起来不同。所以为什么?我用完全相同的一组参数调用它。

编辑:经过更多的测试后,似乎只有在从SQL Management Studio运行参数化查询时才会出现10倍速度下降。

回答

10

我最近看到的一件事是,如果你设置错误的查询参数可能会导致重大问题。

例如,假设您有一个索引varchar列的参数,并使用SqlCommand的AddWithValue()方法从.Net进行设置。你在这个场景中受到伤害的世界。 .Net使用unicode字符串,并将您的参数设置为nvarchar而不是varchar。现在,sql server将无法使用您的索引,并且您会看到显着的性能损失。

+0

这是一个很好的观点,我之前受到过伤害。 – 2009-02-23 14:34:48

+0

我最近也看到了这种行为。会造成一些重大的性能问题。 – Kibbee 2009-02-23 15:23:50

+0

@Kibbee:我想这是你在一个或两个月前的另一个SO问题中的评论,这让我开始研究这种行为。幸运的是,我永远不会使用AddWithValue,并且总是明确指定参数类型,所以它在我的任何旧代码中都不是问题。 – 2009-02-23 15:40:16

4

找出它们是否使用相同的执行计划是在运行时显示它。在管理工作室中使用“包含实际执行计划”,看看有什么不同。

+0

你打我的答案 - 我打字的时候你的答案到来。 – SAMills 2009-02-23 14:32:48

2

参数化查询有很多advantages,其中包括经常性能提高。查询

  • 缓存
  • 最小
  • 字符串连接问题解决SQL注入
  • 数据没有处理
之前被转换为字符串
-1

存储过程可以运行,因为速度更快执行计划由sql server缓存。

但10倍的表现是可疑的。 在清除存储的执行计划后第一次运行相同吗?您可以使用这些命令清除缓存。但他们清除了整个服务器缓存,因此只能在开发服务器上进行。

DBCC FREEPROCCACHE 
DBCC FLUSHPROCINDB (<dbid>) 

您是否直接在SQL服务器上运行这些以消除性能测试中的任何网络I/O?

我的猜测是,它第一次运行缓慢,然后一旦缓存它运行得更快。

3

连接级别设置可以在某些情况下是至关重要的,尤其是ANSI NULLSCONCAT NULL YIELDS NULL,等等。特别是,如果你有计算坚持索引列(其中包括推动“XML”列),那么就不会信任预先计算的索引值如果设置不兼容,并且将重新计算每一行(即表扫描而不是索引查找)。

相关问题