我的MVC应用程序中有一个查询,大约需要20秒才能完成(使用NHibernate 3.1)。当我在Management studio上手动执行查询时,需要0秒。
我在SO上遇到过类似问题的类似问题,所以我将我的测试更进了一步。
我使用Sql Server Profiler拦截了查询,并在我的应用程序中使用ADO.NET执行了查询。
我从Profiler获得的查询类似于:“exec sp_executesql N'select ....”
我的ADO.NET代码:
SqlConnection conn = (SqlConnection) NHibernateManager.Current.Connection;
var query = @"<query from profiler...>";
var cmd = new SqlCommand(query, conn);
SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
return RedirectToAction("Index");
此查询也非常快,没有时间执行。
另外,我在Profiler上看到了一些非常奇怪的东西。从NH执行时,查询具有以下统计信息:
读取:281702 写道:0
来自ADO.NET的那个:
读取:333 写道:0
任何人都有任何线索?我可以提供任何信息来帮助诊断问题吗?
我认为它可能与某些连接设置有关,但ADO.NET版本使用的是NHibernate的相同连接。
提前致谢
更新:
我正在使用NHibernate LINQ。查询是巨大的,但是是一个分页查询,只提取了10条记录。
传递给“exec sp_executesql”的参数是:
@ p0 int,@ p1 datetime,@ p2 datetime,@ p3 bit,@ p4 int,@ p5 int
@ p0 = 10,@ p1 ='2009-12-01 00:00:00',@ p2 ='2009-12-31 23:59:59',@ p3 = 0,@ p4 = 1, @ P5 = 0
答案 0 :(得分:8)
我有ADO.NET和NHibernate使用不同的查询计划,我更喜欢参数嗅探对NH版本的影响。为什么?因为我之前使用较小的日期间隔进行了查询,并且存储的查询计划已针对它进行了优化。
之后,在查询大日期间隔时,使用了存储的计划,并且需要很长时间才能得到结果。
我确认这实际上是问题因为一个简单的问题:
DBCC FREEPROCCACHE -- clears the query-plan cache
再次快速查询。
我找到了两种方法来解决这个问题:
query = query.Where(true)
,当预期结果集较小时(日期间隔明确)。这样就可以创建两个不同的查询计划,一个用于大型数据集,另一个用于小型集。我尝试了两种选择,两种方法都有效,但选择了第二种方法。这有点 hacky 但是我的情况非常好,因为数据是按日期统一分配的。
答案 1 :(得分:6)
我遇到与OP完全相同的问题。我试着@psousa建议注入一个“选项(重新编译)”,这确实提高了我的表现。但最后我发现简单地更新SQL Server的统计数据对我来说是个窍门。
update statistics tablename;
我最终退出我的代码以注入“选项(重新编译)”。我意识到这可能不是每个人的答案,但想分享,因为这是我的问题的原因。
答案 2 :(得分:2)
查看提供给sp_executesql存储过程的参数。如果参数以nvarchar(N'value')的形式提供,并且它们引用的列是varchar,则SQL Server将使用效率非常低的查询计划。这是我遇到的所有性能问题的根本原因,这些问题表现出这些症状(应用程序速度慢,SSMS速度快)。
答案 3 :(得分:0)
您没有指定查询或其结果集的大小,但是使用nHibernate获取大量实体时存在问题。
基本上,“保湿”物体的时间就是这么长的时间
您可以尝试打开反射优化器,或使用IStatelessSession
看到我有here的som建议。