NHibernate分页性能(更好的选择)

在那个简单的案例中:

public class Person { public int Id {get;set;} public int Name {get;set;} } 
  • 我需要生成一个带分页和排序的网格
  • 我的数据库有大约10万人

什么选项有更好的表现:

1)第一次获取所有元素并在利用NHibernate First Level Cache之后,例如:

 personRep.FindAll().OrderBy(s =>s.Name).AsPagination(pageNumber,pageSize); 

Obs。:AsPagination是一种扩展方法……

2)从数据库中只获取实际页面,例如:

  public virtual IList GetPaginedList(int __pageIndex, int __pageSize,out int __total) { var _rowCount = Session.CreateCriteria(typeof(T)) .SetProjection(Projections.RowCount()).FutureValue(); var _results = Session.CreateCriteria(typeof(T)) .SetFirstResult(__pageIndex * __pageSize) .SetMaxResults(__pageSize) .Future(); __total = _rowCount.Value; return _results; } 

第二种选择是最合适的选择。

当您(用户)甚至不“使用”所有这些实例时,一次性检索所有实例是没用的。

如果’Person’类是一个有很多关联的’重’类,那么创建一个’PersonView’类会更好,它只包含你想要在Grid中显示的属性。

你不必映射那个PersonView类,你只需要“导入”它,这样NHibernate就知道它的存在。 然后,在Person类上创建一个查询,并定义必须使用AliasToBean TransformerPerson实例转换为PersonView实例。

通过这样做,NHibernate将能够生成一个只从DB中检索必要列的查询,并将使用它填充PersonView实例。

像许多数据检索性能问题一样,哪些更好将取决于使用场景。

如果用户可能会在数据过于陈旧无法使用之前浏览大部分或全部页面,则选项1会更好。 在总结果集相对较小(2-3页)的情况下,以及结果集不会发生太大变化(即从数据库中提取用户权限)的情况下,它也会更好,允许您将整个数据集存储在内存中通过消除网络往返,提高未来运行的性能。

选项2更适用于涉及长数据页和/或总结果集,“宽”记录的情况,或者经常变化的数据,本地缓存不会带来太多好处。 它将检索记录的成本分摊到结果集的使用范围内,达到显示它们所需的程度。 分页结果的这种“延迟加载”确实增加了获取记录的总时间和开销(因为有更多的往返次数),但是您的用户更有可能注意到并抱怨他们的搜索结果有10秒的周转时间每页超过半秒。