没有 DBType 的 AddWithValue 导致查询运行缓慢
我一直在使用 cmd.Parameters.AddWithValue,并且没有指定 DBType(int、varchar、...)来运行查询。 查看 SQL Profiler 后,似乎使用此方法运行的查询比指定数据类型时运行得慢很多。
为了让您了解它慢了多少,这里有一个例子。 该查询是对单个表的简单查找,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 作为数据库。
[更新]
经过一番挖掘,我找到了这个 博客文章,可能相关。 似乎 .Net 中的字符串值(因为它们是 unicode)会自动创建为 nvarchar 参数。 我必须等到周一开始工作,看看是否可以做一些事情来解决这个问题。 看起来我仍然必须设置数据类型,这是我试图避免的。
这个问题并没有出现在我所做的每个查询中,只是选择了几个查询,所以我仍然可能只是在有问题的查询中设置 DBType,但我正在寻找一个更通用的问题解决方案。
I've been using cmd.Parameters.AddWithValue, and not specifying a DBType (int, varchar,...) to run queries. After looking at SQL Profiler, it seems that queries run with this method run a lot slower than when you specify the data type.
To give you an idea of how much slower it is, here's an example. The query is a simple lookup on a single table, and the column in the where statement is indexed. When specifying the data type, a certain query runs in about 0 MS (too small for sql server to measure), and requires 41 reads. When I remove the DBType, it can take around 200 ms, and 10000 reads for the query to complete.
I'm not sure if it's just SQL Profiler misreporting values, or if these values are actually correct, but it is reproducible, in that I can add and remove the DBType, and it will produce the values given in SQL Profiler.
Has anybody else come across this problem, and a simple way to fix it. I realize that I could go in adding the data type in all over my code, but that seems like a lot of stuff to add in, and if there is an easier way to fix it, that would be much appreciated.
[EDIT]
After some initial testing (running both scenarios in a loop) it seems like the values that profiler gives are accurate.
Just as added information I'm running .Net 2.0 on Windows XP Pro, and SQL Server 2000 on Windows 2000 for the DB.
[UPDATE]
After some digging around, I was able to find this blog post, which may be related. Seems that string values in .Net (since they are unicode) are automatically created as nvarchar parameters. I'll have to wait until monday when I get into work to see if I can do something around this which fixes the problem. Still it seems as though I would have to set the data type, which was what I was trying to avoid.
This problem doesn't show up with every query I did, just a select few, so I still may just resort to setting the DBType in the queries with problems, but I'm looking for a more generalized solution to the problem.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
该问题与 SQL Server 如何进行隐式类型转换有关。 如果使用 NVARCHAR 值(即 N'some text')过滤 VARCHAR 列,SQL 别无选择,只能将该列转换为 NVARCHAR,因为 NVARCHAR 无法隐式转换回 VARCHAR。
最好的解决方法是指定类型或将数据库列更改为 NVARCHAR。
The problem is related to how SQL server does implicit type conversions. If you filter a VARCHAR column using an NVARCHAR value (ie. N'some text'), SQL has no choice but to convert the column to NVARCHAR as NVARCHAR cannot be implicitly converted back to VARCHAR.
Your best workaround is either to specify the type or to change your database column to be NVARCHAR.
我刚刚遇到了这个确切的问题。 我有一个包含很多字符列的旧数据库。 在没有指定列类型的情况下,我的一个查询花了几分钟才得到结果。 (默认为 nvarchar。)指定列类型导致结果需要几秒钟的时间。
我想我将尝试将每个字符串查询作为字符类型,看看效果如何。
更新
实际上,在阅读这篇博客文章后:存档
我决定采用此解决方案:
I just ran into this EXACT problem. I've got a legacy database with a lot of char columns. Without specifying the type of column the results took a couple of minutes on one of my queries. (It default to nvarchar.) Specifying the column type caused the results to take seconds.
I think I'm going to try having every string query as a char type and see how that goes.
Update
Actually, after reading this blog post:archive
I've decided to go with this solution:
这两种情况生成的 SQL 语句是什么?
我怀疑当您没有明确指定它时,它会将值假定为 varchar 。
例如
从订单中选择 OrderId WHERE OrderId = 1001
VS
从订单中选择 OrderId WHERE OrderId = '1001'
What is the SQL statement generated in both the cases?
I am suspecting that it assumes the value as varchar when you don't explicitly specify it.
e.g.
SELECT OrderId FROM Orders WHERE OrderId = 1001
vs
SELECT OrderId FROM Orders WHERE OrderId = '1001'