2011-01-31 58 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