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

时间:2012-03-28 23:13:12

标签: c# nhibernate fluent-nhibernate mapping paging

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

我们从中获取数据的表有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>();

我的想法已经不多了。因此,如果有人能指出我们正确的方向,我会非常感激。

由于

2 个答案:

答案 0 :(得分:3)

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

当然它在服务器上排序,但是在对它们进行排序之前,将计算所有记录的总和。您应该能够通过使用SQL事件探查器或通过创建计算总和并将其插入查询的SQL函数/过程来验证它,然后检查它的调用频率。如果你有一个拥有500,000多名成员的桌子,它将被称为500,000+次;没有办法解决它。

你可以尝试的是:

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

答案 1 :(得分:0)

  1. 第一个选项是预先计算数据并准备好从表格中查询数据
  2. 创建视图并将其映射到数据传输对象。在视图中,您可以先约束数据集,然后进行计算。减少要进行计算的数据可以使查询执行得更快。