sqlparameter性能不佳

时间:2011-12-21 12:52:23

标签: c# sql-server ado.net sqlcommand sqlparameter

我有一个Web服务,因此处理程序会一直多次被同时调用。

我在里面创建了SqlConnection和SqlCommand。我必须执行大约7个不同的命令。不同的命令需要各种参数,所以我只需添加一次:

command.Parameters.Add(new SqlParameter("@UserID", userID));
command.Parameters.Add(new SqlParameter("@AppID", appID));
command.Parameters.Add(new SqlParameter("@SID", SIDInt));
command.Parameters.Add(new SqlParameter("@Day", timestamp.Date));
command.Parameters.Add(new SqlParameter("@TS", timestamp));

然后在执行期间我只需更改CommandText prorerty,然后调用ExecuteNonQuery();或ExecuteScalar();

我面临性能问题。 例如,小调试和分析显示,该命令

command.CommandText = "SELECT LastShowTS FROM LogForAllTime WHERE UserID = @UserID";
平均需要大约50毫秒。如果我将其更改为:

command.CommandText = "SELECT LastShowTS FROM LogForAllTime WHERE UserID = '" + userID.Replace("\'", "") + "'";

然后只需要1毫秒的时间!

我无法弄清楚在哪里调查问题。

2 个答案:

答案 0 :(得分:15)

听起来它已经缓存了一个非典型@UserID值(早期版本之一)的查询计划,并且正在为以后的查询重用一个糟糕的计划。这在第二种情况下不是问题,因为每个都有一个单独的计划。我怀疑你只需要添加:

OPTION (OPTIMIZE FOR UNKNOWN)

查询,这将使其不太热衷于盲目地重复使用计划。


替代理论:

userID(在C#中)的类型与UserID的类型(在数据库中)之间可能不匹配。这可以像unicode vs ANSI一样简单,也可以int vs varchar[n]等。如果有疑问,在配置参数时非常具体,添加它正确的子类型和大小。

澄清

事实上,这里的问题似乎是C#string(unicode)和数据库varchar(n)(ANSI)之间的区别。因此,SqlParameter应明确添加(DbType.AnsiString)。

答案 1 :(得分:0)

您向服务器发送了七倍以上的数据,因此速度会慢一些。

此外,如果您的userID字符串具有不同的长度,则在SQL参数中设置显式长度将允许它更好地重用查询。