我一直在使用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有问题,但我正在寻找一个更通用的问题解决方案
答案 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'