为什么exec sp_executesql比内联sql慢得多?

时间:2015-06-01 04:23:57

标签: c# sql-server ado.net full-text-search sp-executesql

我在管理工作室测试了这个查询,执行速度非常快(不到一秒)

declare @p_Message_0 varchar(3) = 'whh'
declare @p_CreatedTime_0 datetime = '2015-06-01'

SELECT count(1) FROM (SELECT * FROM [Logs](nolock) WHERE CONTAINS([Message], @p_Message_0) AND [CreatedTime]<@p_CreatedTime_0) t
SELECT t2.* FROM (SELECT t.*,ROW_NUMBER() OVER (ORDER BY Id DESC) as rownum FROM (SELECT * FROM [Logs](nolock) t WHERE CONTAINS([Message], @p_Message_0) AND [CreatedTime]<@p_CreatedTime_0) t) t2 WHERE rownum>0 AND rownum<=20

这样的执行计划: enter image description here

然后我将其移至C#ado.net,它以

运行
exec sp_executesql N'SELECT count(1) FROM (SELECT * FROM [Logs](nolock) WHERE CONTAINS([Message], @p_Message_0) AND [CreatedTime]<@p_CreatedTime_0) t
SELECT t2.* FROM (SELECT t.*,ROW_NUMBER() OVER (ORDER BY Id desc) as rownum FROM (SELECT * FROM [Logs](nolock) t WHERE CONTAINS([Message], @p_Message_0) AND [CreatedTime]<@p_CreatedTime_0) t) t2 WHERE rownum>0 AND rownum<=20',N'@p_Message_0 varchar(3),@p_CreatedTime_0 datetime',@p_Message_0='whh',@p_CreatedTime_0='2015-06-01'

这一次运行真的很慢(大约30s)。执行计划如:enter image description here

我不知道是什么让这两个计划有所不同。 Sql server是2008 R2 SP2,我试过参数提示和OPTION(RECOMPILE),两者都不适用于我。

1 个答案:

答案 0 :(得分:1)

尝试更新统计信息。第一个使用具有今天日期的变量。变量没有被嗅探,所以你会得到一个猜测的分布。第二个使用参数。这可以被嗅到。

如果今天的数据尚未更新,SQL Server将认为该日期不存在任何行,因此将在此基础上提供计划。例如嵌套循环计划,估计执行一次TVF但实际执行多次。

AKA the ascending date problem