在我继承的代码中,我有一个 SqlDataSource,它有一个相当复杂的 select 语句,对于某些 SelectParameters,总是超时(“超时已过期。在操作完成之前超时时间已过或服务器没有响应。”)。
当我在管理工作室中使用相同的参数运行完全相同的查询时,查询永远不会超时,并且总是不到一秒。
有谁知道这里可能出现什么问题?我无法理解它。
在我继承的代码中,我有一个 SqlDataSource,它有一个相当复杂的 select 语句,对于某些 SelectParameters,总是超时(“超时已过期。在操作完成之前超时时间已过或服务器没有响应。”)。
当我在管理工作室中使用相同的参数运行完全相同的查询时,查询永远不会超时,并且总是不到一秒。
有谁知道这里可能出现什么问题?我无法理解它。
只是在黑暗中拍摄:参数实际上并不相同。在 SSMS 中,您为查询传递 ASCII 参数,而在 ADO.Net 中,您传递 Unicode 参数。当是一个字符串SqlCommand.Parameters.AddWithValue("@myParam", myValue)
时,将添加一个 NVARCHAR 类型的参数。myValue
由于 SQL 中的转换规则,如果你有SELECT ... FROM ... WHERE myField = @myParam
并且 myField 是 Ascii (VARCHAR) 并且 @myParam 是 Unicode (NVARCHAR),那么执行必须执行表扫描,不能在 myField 上使用索引,与 SSMS 执行相比导致性能糟糕.
正如我所说,这只是在黑暗中拍摄,但这是一个常见的陷阱,调试起来相当微妙。
可能是锁定/阻塞,如果人们在数据库中工作,您的选择可能会等到他们的事务完成。超时将被命中或错过,具体取决于数据库中的其他事务。
在管理工作室中,运行SET SHOWPLAN_ALL ON
,然后运行您的查询。在输出中查找“SCAN”。如果你有一个表或索引扫描,你更有可能成为锁定/阻塞的受害者,因为你必须处理整个索引/表,任何锁定一行的人都会迫使你等待。
当您运行应用程序时,屏幕没有刷新在管理工作室中快速运行:
EXEC sp_lock
它将为您提供一些当前正在进行的锁定的基本信息。
尝试以下操作,也许这会澄清发生了什么:
在 sql profiler 中,捕获复杂的 SQL 语句转换成的确切语句,并在 Viual Studio 中运行它。
当有问题的 sql 语句正在运行时,请在管理工作室中检查活动监视器。它可以给你一个想法,可能是什么阻止了 sql。
重要的是要查看同时运行的其他内容。应用程序是多线程的吗?sql连接是否在使用后立即关闭/处理(如果没有,它可能不会及时关闭)?多个线程使用相同的sql连接吗?