NHibernate执行查询需要很长时间

4

这是使用Fluent NHibernate完成的。

我有一个NHibernate查找,从一张表中检索数据。如果我将生成的SQL通过查询分析器运行,它需要大约18毫秒才能运行。

使用NHProfiler,我得到了这个查询的持续时间为约1800毫秒 - 比SQL慢100倍!

Query duration
 - Database only:1800ms
 - Total: 1806ms

正在填充的对象包含一个子类,但是这个子类是从NHibernate第二级缓存中加载的。
返回的数据是分页的(每次查询50条),尽管据我所知,这不会产生任何影响。
我还在运行计数器,同样,在查询分析器中需要大约4毫秒,而根据NHProfiler需要大约1800毫秒。
NH Profiler显示的是查询执行时间还是检索、映射类和构造对象图的完整时间?如果是前者,为什么要比直接运行查询花费更长的时间?
编辑:刚刚发现Ayende关于NH Profiler中Query Duration值的帖子:http://ayende.com/Blog/archive/2009/06/28/nh-prof-query-duration.aspx - 因此,确实是查询数据库花费了很长时间。

ADO.NET需要多久时间? - Michael Maddox
当您使用像ants或dottrace这样的分析器对代码进行分析时,主要的瓶颈是什么? - Paco
使用 ADO.NET 所需的时间仅为 NHibernate 的一小部分。目前我没有安装任何性能分析软件,所以我将先解决这个问题,看看它会说些什么。 - dave clements
Ants 显示整个过程仅需要 160 毫秒,这是我的测试和 NH Profiler 告诉我的时间的十分之一。我已经尝试过使用 NH Profiler 分离重新运行,以防这是问题,但这也没有任何区别。 - dave clements
测量不同的时间会让人感到困惑。当您使用System.Diagnostics.Stopwatch来计时调用使用NHibernate和数据库的方法的代码的实际执行时间时,需要多长时间?我希望这可以给您带来“真实”的时间。 - Paco
使用秒表给我相同的结果 - 大约1800毫秒 - dave clements
2个回答

8

最终成功追踪到了问题。

对象的主键在数据库中是一个varchar。当NHibernate运行查询时,它将该值转换为nvarchar。不幸的是,在查看NH Profiler生成的SQL时,这并不明显。由于SQL将nvarchar转换回varchar,导致速度变慢。

我已经指定了使用自定义类型的映射。

map.Id(x => x.Id).CustomType("AnsiString");

问题已经解决了

感谢大家的帮助 :)


今天这个对我帮助很大。 - Matthew Talbert
我遇到了同样的问题,这个帮助很大。 - Ken Henderson

1

通常这些问题都与您和数据库之间的网络有关。QA通常直接连接到数据库,只需将原始数据发送回格式化即可。您的应用程序可能会将结果集转换为数据集或类似结构。为了证明这一点,请更改一小部分代码(而不是整个数据层),使用SQL Data Reader读取您的数据。只需读取所有记录而不尝试解析所有列并保存数据。它很可能会像您的网络允许的那样快速执行。


我刚刚使用数据读取器运行了NHibernate生成的确切查询,总执行时间仅略超过1毫秒,所以不幸的是,这似乎不是网络延迟问题。 - dave clements
这就是我的观点...现在尝试读取你的数据并将每列提取到你的“行容器”中,无论那是什么。你可能会看到速度变慢。 - No Refunds No Returns
我刚刚重新运行了一下以进行检查,创建连接、运行查询(我正在对简单计数进行操作,以使其尽可能容易),并读取数据只需要略微超过一毫秒的时间。 - dave clements

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接