fluent nhibernate查询使用分页对映射公式进行排序需要很长时间

本文关键字:排序 长时间 查询 nhibernate 分页 映射 fluent | 更新日期: 2023-09-27 18:29:32

我们有一个数据网格来为我们的客户显示成员记录。最近,我们的任务是为我们的应用程序添加分页,以便我们的大型客户(500000多名会员)。

我们从中获取数据的表有10列。当把我们的数据拉到我们的应用程序中时,我们添加了3个额外的列,这些列都是计算字段

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

其中"this_"是成员表的别名,tableX表示我们需要从中获取数据的另一个表。

在我们的查询中,我们必须提供对列进行排序的能力,但我注意到,当我尝试对计算字段进行排序时,与对表中存在的列进行order BY相比,它需要花费大量的时间。这是有道理的,因为它需要更长的时间,但当只加载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>();

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

感谢

fluent nhibernate查询使用分页对映射公式进行排序需要很长时间

这实际上不是一个NHibernate问题,而是一个普通的SQL问题。

当然,它是在服务器上排序的,但在排序之前,将计算所有记录的总和。您应该能够通过使用SQL探查器或创建一个计算总和的SQL函数/过程来验证这一点,并将其插入到查询中,然后检查调用频率。如果你有一个拥有500000多名成员的表,它将被调用500000多次;根本没有办法。

你可以试试这个:

  1. 请确保在Claims.ID上使用索引(外键即可)
  2. 复制&粘贴生成的SQL并直接在数据库上运行它,看看这是否需要很长时间
  3. 如果您不介意有某种形式的冗余,您可以为Members表中的计算字段添加新列,并使用Claims表上的触发器(插入/删除)相应地更新这些列
  4. 如果你不想使用触发器,你也可以创建一个计划的数据库事件来进行计算。(当然,只有在不需要实时数据的情况下,这才是一种选择)
  1. 第一种选择是预计算数据,并准备好从表中查询它们
  2. 创建视图并将其映射到数据传输对象。在视图中,您可以首先约束数据集,然后进行计算。要进行计算的数据更少,查询执行速度更快