没有DBType的AddWithValue导致查询运行缓慢

时间:2008-12-05 22:04:30

标签: .net sql ado prepared-statement

我一直在使用cmd.Parameters.AddWithValue,而没有指定DBType(int,varchar,...)来运行查询。在查看SQL事件探查器之后,使用此方法运行的查询似乎比指定数据类型时运行慢得多。

为了让您知道它的速度有多慢,这是一个例子。该查询是对单个表的简单查找,并且where语句中的列已编制索引。指定数据类型时,某个查询运行大约0 MS(对于要测量的sql server来说太小),并且需要41次读取。当我删除DBType时,它可能需要大约200毫秒,并且10000次读取才能完成查询。

我不确定它是仅仅是SQL Profiler误报的值,还是这些值实际上是正确的,但它是可重现的,因为我可以添加和删除DBType,它将产生SQL Profiler中给出的值。

是否有其他人遇到过此问题,以及解决此问题的简单方法。我意识到我可以在我的代码中添加数据类型,但这似乎要添加很多内容,如果有更简单的方法来修复它,那将非常感激。

[编辑]

经过一些初步测试(在循环中运行两个场景)之后,探测器给出的值似乎是准确的。

正如添加的信息一样,我在Windows XP Pro上运行.Net 2.0,在Windows 2000上运行SQL Server 2000用于数据库。

[UPDATE]

经过一番挖掘,我找到了这个blog post,这可能是相关的。似乎.Net中的字符串值(因为它们是unicode)会自动创建为nvarchar参数。我将不得不等到星期一,当我开始工作,看看我是否可以做一些解决问题的方法。似乎我必须设置数据类型,这是我试图避免的。

这个问题没有出现在我做的每一个查询中,只有少数选择,所以我仍然可能只是在查询中设置DBType有问题,但我正在寻找一个更通用的问题解决方案

3 个答案:

答案 0 :(得分:5)

问题与SQL Server如何进行隐式类型转换有关。如果使用NVARCHAR值(即N'some text')过滤VARCHAR列,则SQL别无选择,只能将列转换为NVARCHAR,因为NVARCHAR无法隐式转换回VARCHAR。

您最好的解决方法是指定类型或将数据库列更改为NVARCHAR。

答案 1 :(得分:2)

我刚遇到这个问题。我有一个包含很多char列的遗留数据库。如果没有指定列的类型,结果在我的一个查询上花费了几分钟。 (默认为nvarchar。)指定列类型会导致结果花费几秒钟。

cmd.Parameters.AddWithValue("charcolumn", "stringvalue");
cmd.Parameters[0].SqlDbType = SqlDbType.Char;

我想我会尝试将每个字符串查询作为char类型,看看情况如何。

[编辑]

实际上......看完之后: http://www.u2u.info/Blogs/U2U/Lists/Posts/Post.aspx?ID=11

我决定采用这种解决方案:

cmd.Parameters.AddWithValue(colName, val);
if(val is string)
  cmd.Parameters[i].DbType = DbType.AnsiString;

答案 2 :(得分:0)

两种情况下生成的SQL语句是什么?

我怀疑当你没有明确指定它时,它会将值假定为varchar。

e.g。 SELECT OrderId FROM Orders WHERE OrderId = 1001
vs SELECT OrderId FROM Orders WHERE OrderId = '1001'