繁体   English   中英

分页大结果集的最佳方法是什么-Java

[英]what is best way to paging big Resultset -Java

我正在寻找从性能的角度来看最好的方法,在网页上部分显示结果集,让我们说每页 10 个项目,如果用户想要查看更多结果,他按“下一步”btn。 我认为(可能是错误的)当按下“下一步”按钮时,它应该是对服务器的新请求??

目前我正在尝试学习 Java,GWT

谢谢你!

PS:对不起我的英语。

答案取决于用户的行为:查看第 2 页、第 10 页或第 100 页的频率。

如果他们很少看第 2 页,从不看第 10 页或第 100 页,那么重新提交请求可能没问题。

如果他们通常看第 2 页,经常看第 10 页,偶尔看第 100 页,那么部分缓存会很有用:缓存前 100 个(或 200,或 300 个)结果,并仅在它们去时重新提交查询过去的那些结果。 我可能会将缓存存储在用户的会话中,尽管如果您的应用程序服务器是集群的,您必须考虑一下。

如果他们总是翻阅每个结果? 部分缓存仍然是答案,因为您不想在内存中存储大块数据。

由于您的标签中有“GWT”,我假设您的服务器应用程序在 Google App Engine (GAE) 上运行。

  • 一种方法是让您的第一个查询获得所有结果,将它们存储在数据库中,显示前 20 个,然后让下一个/上一个链接从数据库中提取存储数据的子集。 当您的用户会话超时时,您必须记住从数据库中删除这些结果!

  • 另一种方法是获取每个页面视图上的所有结果,但跳过结果,直到达到所需的 20 个子集,然后仅输出这些结果。

我认为在下面的 GAE 中,第二种方法会更好,除非您的查询可能返回 1000 多个结果,GAE 不会让您在一个事务中检索这些结果。

  • 最好的方法是,如果您的数据和键适用于它,则是在查询时提取出正确的 20 个数据项。 但是除非您的数据具有连续递增的整数键,否则这可能很难做到。

您通常只能从数据库中获得一个“页面”。

让我们说一个查询

select * from mytable where column1="a";

将给出 1000 条记录。 然后获取一个页面就像(mysql):

select * from mytable where column1="a" limit 0, 10;

对于第 1 页(0 到 10),第 2 页将被检索为:

select * from mytable where column1="a" limit 10, 20;

等等。 如果数据很大(1000 条记录),但不是很大(1000 000 条记录),您也可以一次给出整个数据集并使用javascript 进行分页。 这具有额外的优势,即可以在客户端进行排序。

如果由于内存限制而无法使用基于缓存的方法,请使用基于查询的方法。 调整搜索查询上的 WHERE 子句,以根据用户请求的页面明确选择数据。 这种方法要求您在页面请求中来回传递额外的上下文信息。

一种方法是使用逻辑行 ID(或主键)来获取页面,这些逻辑行 ID(或主键)分隔页面并标识结果集中的每一行。

假设您有一个非常简单的表,其中包含行 ID 的数字序列。 如果每页显示 100 行,并且用户请求了第二页,则应按如下方式调整 WHERE 子句:

select col, col2 from my_table where
row_id > 100
and row_id <= 200
order by rownum asc

您可以缓存/检索 web 层、后端层(例如 ejb)或数据库层(作为最后一个“限制”或 row_id 语句)中的记录。 您应该使用哪种方法取决于您的要求(如 kdgregory 所说)。

最流行的一种是使用会话将它们缓存在 web 层。

如果您使用的是 JPA(在 GAE 上效果很好),您可以使用

查询#setFirstResult(int startPosition)

查询#setMaxResults(int maxResult)

这篇文章可能会有所帮助: Paging large data sets with a LazyList

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM