10

我有一个网络服务,所以处理程序一直被同时调用多次。

在里面我创建了 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("\'", "") + "'";

那么它平均只需要1ms!

我只是不知道在哪里调查问题。

4

2 回答 2

16

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

OPTION (OPTIMIZE FOR UNKNOWN)

到查询,这将减少盲目重用计划的热情。


替代理论:

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

澄清

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

于 2011-12-21T12:56:27.510 回答
0

您向服务器发送的数据多 7 倍,因此速度会变慢。

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

于 2011-12-21T12:56:51.873 回答