我在 C# 中遇到了 NHibernate 的问题。
当它想要执行查询时应用程序面临 ADO 超时错误,但是当我使用 SQL Profiler 捕获查询,然后我在 SQL Server 的新查询中运行它时,恰好只需要 2 秒
有什么想法吗??
最佳答案
当您从 SQL Profiler 捕获查询并在 SSMS 中运行它时,您是否将其作为 sp_executesql 查询运行?我在使用 NHibernate 2.1GA 时遇到了类似的问题,这个答案适用于那个版本,我还没有转换到 NH3。 NH Profiler 是一个很棒的工具,但它有助于将 SQL 提取到格式化的查询中,该查询不代表发送到服务器的实际查询。
问题在于 NHibernate 向 sp_executesql 提供字符串参数的方式。字符串参数类型为 nvarchar,长度等于值的长度。例如,此查询限制了两个列,分别是 varchar(4) 和 varchar(20):
exec sp_executesql N'SELECT this_.Column0, this_.Column1 FROM MySchema.MyTable this_ WHERE this_.Column0 = @p0 and this_.Column1 = @p1',N'@p0 nvarchar(4),@p1 nvarchar(7)',@p0='Val0',@p1='Value01'
此查询计划使用索引扫描并耗时 17 秒。将 nvarchar 更改为 varchar 生成了一个使用索引查找并在 < 2 秒内执行的计划。这在 SSMS 中是可重现的。
根本原因是 NHibnerate 在默认情况下对 varchar 列使用 DbType.String 而不是 DbType.AnsiString。我的解决方案是添加 Fluent NHibernate 约定,将所有字符串映射更改为 AnsiString,这导致 NHibernate 创建以 varchar 形式提供参数的查询。
关于c# - 查询在 NHibernate 中出现超时错误,但在 SQL Server 中却没有,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4530406/