流畅的 nhibernate 查询需要很长时间才能使用分页对映射公式进行排序

问题描述 投票:0回答:2

我们有一个数据网格来为我们的客户显示会员记录。我们最近的任务是向我们的应用程序添加分页,以便我们的大客户(超过 500,000 名会员)能够使用。

我们从中获取数据的表有 10 列。当将数据拉入应用程序时,我们添加了 3 个附加列,它们都是计算字段

SELECT SUM(tableX.Cost) FROM tableX WHERE tableX.ID = this_.ID

其中“this_”是我们的members表的别名,tableX代表我们需要从中获取数据的另一个表。

在我们的查询中,我们必须提供对列进行排序的能力,但我注意到,当我尝试对计算字段进行排序时,与我对表中存在的列进行排序相比,需要花费大量时间。这是有道理的,因为它需要更长的时间,但是当只加载 1000 条记录需要几分钟的时间时,就会有 500 多个页面需要浏览。然后我觉得这使得寻呼毫无意义。

我已经研究过是否可以使用 nhibernate 进行二级缓存,但从我到目前为止所读到的内容来看,我不确定是否可以解决这个问题。

顺便说一句,其中一张地图是:

Map(x => x.Cost)
    .Formula(@"(SELECT SUM(_Claims.Cost) FROM _Claims WHERE _Claims.ID = this_.ID")
    .Nullable();

以及查询

    var list = CurrentSession()
               .SetFirstRsult(startPos)
               .SetMaxResults(1000)
               .SetTimeout(100)
               .Add(Restrictions.Eq("ClientID", _clientID));

    if(isASC)
    {
        list.AddOrder(Order.Asc(Projetions.Property(_propertyString)));
    }
    else
    {
        list.AddOrder(Order.Desc(Projetions.Property(_propertyString)));
    }

    return list.List<Member>();

我对此没有什么想法了。因此,如果有人能为我们指明正确的方向,我将非常感激。

谢谢

c# pagination nhibernate mapping fluent-nhibernate
2个回答
3
投票

这实际上与其说是一个 NHibernate 问题,不如说是一个一般的 SQL 问题。

当然是在服务器上排序的,但是会先计算所有记录的总和,然后才能排序。您应该能够通过使用 SQL 分析器或创建计算总和并将其插入到查询中的 SQL 函数/过程来验证这一点,然后检查调用的频率。如果你的桌子有超过 500,000 名会员,它将被调用 500,000+ 次;没有办法解决这个问题。

你可以尝试的是这样的:

  1. 确保在
    Claims.ID
    上使用索引(外键可以解决问题)。
  2. 复制粘贴生成的SQL,直接在数据库上运行,看看是否需要很长时间。
  3. 如果您不介意某种形式的冗余,您可以为
    Members
    表中的计算字段添加新列,并在
    Claims
    表上使用触发器(插入/删除)来相应更新这些列。
  4. 如果您不想使用触发器,您也可以创建一个计划的数据库事件来进行计算。 (当然,只有当您不需要实时数据时,这才是一个选择)。

0
投票
  1. 第一个选项是预先计算数据并准备好从表中查询
  2. 创建一个视图并将其映射到数据传输对象。在视图中,您可以先约束数据集,然后进行计算。进行计算的数据较少,查询执行速度更快。
© www.soinside.com 2019 - 2024. All rights reserved.