2011-01-31 71 views
1

我发现了以下的NHibernate超时异常:NHibernate的查询超时

could not execute query 

与内部异常消息是:

Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. 

这NHibernate的代码失败:

shareClassReturns = _session.CreateCriteria<ShareClassTrailingReturn>() 
     .Add(LambdaSubquery.Property<ShareClassTrailingReturn>(x => x.ShareClass.Id).In(GetAvailableShareClassIds())) 
     .Add(LambdaSubquery.Property<ShareClassTrailingReturn>(x => x.ShareClass.Id).In(GetShareclassIdsInCalculationGroup(peerGroups, classificationTypes))) 
     .Add<ShareClassTrailingReturn>(c => c.CurrencyId == "GBP") 
     .AddShareClassReturnOrder(order) 
     .CreateCriteria<ShareClassTrailingReturn>(scr => scr.ShareClass, JoinType.InnerJoin) 
     .Add(ApplicableIdentifiers(searchExpression)) 
     .AddShareClassOrder(order) 
     .SetMaxResults(pageSize) 
     .List<ShareClassTrailingReturn>(); 

这是我通过NHibernate Profiler看到的SQL(虽然我已经整理了一下,并全部替换了我与select top 25 *选择的项目,以使其更具可读性):

SELECT top 25 * 
FROM  offline.ShareClassTrailingReturn this_ 
     inner join ShareManager.ShareClass shareclass1_ 
      on this_.SCTR_ShareClassId = shareclass1_.ShareClass_Id 
     left outer join DCS.ShareClassInfo shareclass1_1_ 
      on shareclass1_.ShareClass_Id = shareclass1_1_.[ShareClassInfo_MSShareClassId] 
WHERE  
    this_.SCTR_ShareClassId in 
    (
     SELECT this_0_.[Fund_ID] as y0_ 
     FROM dbo.Fund this_0_ 
      inner join CAP.DataUniverse datauniver1_ 
       on this_0_.[Fund_TypeID] = datauniver1_.[DataUniverse_TypeId] 
       and this_0_.[Fund_CountryID] = datauniver1_.[DataUniverse_CountryID] 
     WHERE datauniver1_.[DataUniverse_SiteId] = 100 /* @p0 */ 
    ) 
    and this_.SCTR_ShareClassId in 
    (
     SELECT this_0_.ShareClass_Id as y0_ 
     FROM dbo.vCalculationGroup this_0_ 
     WHERE 
      this_0_.PeerGroupId in (1,8) 
      and this_0_.ClassificationId in (7,1) 
    ) 
    and this_.SCTR_CurrencyId = 'GBP' 
    and 
    (
     shareclass1_.ShareClass_MEX like '%axa%' 
     or shareclass1_.ShareClass_SEDOL like '%axa%' 
     or shareclass1_1_.ShareClassInfo_RIC like '%axa%' 
     or shareclass1_.ShareClass_ISIN like '%axa%' 
     or shareclass1_.ShareClass_CUSIP like '%axa%' 
    ) 
ORDER BY shareclass1_.ShareClass_Name asc 

如果我改变了NHibernate的标准,所以它不会做的选择对vCalculationGroup,也就是说,如果我删除此行:

.Add(LambdaSubquery.Property<ShareClassTrailingReturn>(x => x.ShareClass.Id).In(GetShareclassIdsInCalculationGroup(peerGroups, classificationTypes))) 

或这从SQL

and this_.SCTR_ShareClassId in 
    (
     SELECT this_0_.ShareClass_Id as y0_ 
     FROM dbo.vCalculationGroup this_0_ 
     WHERE 
      this_0_.PeerGroupId in (1,8) 
      and this_0_.ClassificationId in (7,1) 
    ) 

查询出不再倍。这是否意味着我需要对该视图执行某些操作?像索引或什么?

有人能请建议我该如何解决这个问题?

编辑:我应该补充说,查询可以在SQL Server Management Studio中正常运行,并在大约6秒后返回。尽管如此,当我查看执行计划时,它会报告offline.ShareClassTrailingReturn上缺少索引。这可能是问题吗?

回答

0

我肯定会看看视图上的索引,如果删除该部分使其更好地工作。在你的应用程序中检查你的连接超时值也是值得的。如果您在6秒内说它在Management Studio中正常工作,那可能是您的应用程序连接超时少于六秒(或者缺省值较低)。那将是很好的起点。

这是值得一试的,以避免大量的嵌套子查询。您在生成的SQL中有很多。有时候自己编写SQL或HQL会更有效率,而不是在Criteria或Linq NHibernate API中使用大量复杂的联接。您更有可能为这项工作生成高效的SQL!

+0

很好的建议,谢谢。我们通过连接而不是`In <>()`来解决这个问题 – DaveDev 2011-02-01 20:16:55