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("\'", "") + "'";
然后它只需要1ms的平均值!
我只是无法弄清楚在哪里调查问题。
听起来它已经缓存了一个非典型的@UserID
值(早期版本之一)的查询计划,并且正在为以后的查询重用一个糟糕的计划。 这在第二种情况下不是问题,因为每个都有一个单独的计划。 我怀疑你只需要添加:
OPTION (OPTIMIZE FOR UNKNOWN)
查询,这将使它不那么热衷于盲目地重复使用计划。
替代理论:
您可能在userID
的类型(在C#中)和UserID
的类型(在数据库中)之间不匹配。 这可以像unicode vs ANSI一样简单,也可以是int
vs varchar[n]
等。如果有疑问,在配置参数时要非常具体 ,要用正确的子类型和大小添加它。
澄清
实际上,这里的问题似乎是C# string
(unicode)和varchar(n)
(ANSI)数据库之间的区别。 因此,应该明确地添加SqlParameter
( DbType.AnsiString
)。
您向服务器发送了七倍以上的数据,因此速度会慢一些。
此外,如果您的userID
字符串具有不同的长度,则在SQL参数中设置显式长度将允许它更好地重用查询。