【问题标题】:NHibernate query timing outNHibernate 查询超时
【发布时间】:2011-01-31 15:01:52
【问题描述】:

我收到以下 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 秒后返回。尽管如此,当我查看执行计划时,它报告说离线时缺少索引。ShareClassTrailingReturn。这可能是问题所在吗?

【问题讨论】:

    标签: c# database nhibernate timeout


    【解决方案1】:

    如果删除该部分可以使其更好地工作,我肯定会查看视图上的索引。在您的应用程序中检查您的连接超时也是值得的。如果您说它在六秒内在 Management Studio 中运行良好,则可能是您的应用程序连接超时小于六秒(或默认值小于六秒)。这些将是很好的起点。

    一般来说,避免大量嵌套子查询是值得的。您在生成的 SQL 中有很多内容。有时,自己编写 SQL 或 HQL 比在 Criteria 或 Linq NHibernate API 中使用大量复杂的连接更有效。您更有可能为这项工作生成高效的 SQL!

    【讨论】:

    • 好建议,谢谢。我们通过加入而不是 In&lt;&gt;()'s 解决了这个问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-29
    • 1970-01-01
    • 2011-02-27
    • 1970-01-01
    • 2020-11-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多