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>();
我对此没有什么想法了。所以,如果有人能为我们指明正确的方向,我将不胜感激。
感谢
这实际上不是一个NHibernate问题,而是一个普通的SQL问题。
当然,它是在服务器上排序的,但在排序之前,将计算所有记录的总和。您应该能够通过使用SQL探查器或创建一个计算总和的SQL函数/过程来验证这一点,并将其插入到查询中,然后检查调用频率。如果你有一个拥有500000多名成员的表,它将被调用500000多次;根本没有办法。
你可以试试这个:
- 请确保在
Claims.ID
上使用索引(外键即可) - 复制&粘贴生成的SQL并直接在数据库上运行它,看看这是否需要很长时间
- 如果您不介意有某种形式的冗余,您可以为
Members
表中的计算字段添加新列,并使用Claims
表上的触发器(插入/删除)相应地更新这些列 - 如果你不想使用触发器,你也可以创建一个计划的数据库事件来进行计算。(当然,只有在不需要实时数据的情况下,这才是一种选择)
- 第一种选择是预计算数据,并准备好从表中查询它们
- 创建视图并将其映射到数据传输对象。在视图中,您可以首先约束数据集,然后进行计算。要进行计算的数据更少,查询执行速度更快