我们有一个数据网格来为我们的客户显示会员记录。我们最近的任务是向我们的应用程序添加分页,以便我们的大客户(超过 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>();
我对此没有什么想法了。因此,如果有人能为我们指明正确的方向,我将非常感激。
谢谢
这实际上与其说是一个 NHibernate 问题,不如说是一个一般的 SQL 问题。
当然是在服务器上排序的,但是会先计算所有记录的总和,然后才能排序。您应该能够通过使用 SQL 分析器或创建计算总和并将其插入到查询中的 SQL 函数/过程来验证这一点,然后检查调用的频率。如果你的桌子有超过 500,000 名会员,它将被调用 500,000+ 次;没有办法解决这个问题。
你可以尝试的是这样的:
Claims.ID
上使用索引(外键可以解决问题)。Members
表中的计算字段添加新列,并在 Claims
表上使用触发器(插入/删除)来相应更新这些列。