一次加载一页数据

时间:2010-12-23 14:53:01

标签: java database oracle

我的数据网格中包含超过10k行的页面,因此在首次加载时速度很慢。什么是解决这个问题的最佳方法。我已经读过JDBC分页是这种问题的常用解决方案,但有些人说使用SQL ROWNUM是一个更简单的解决方案,所以我想先问一下。

如果您认为分页是最好的解决方案,请给我一些关于如何继续讨论的指示(链接到实现等)

8 个答案:

答案 0 :(得分:2)

分页是合适的,this question的第一个答案中的策略应该适用于Oracle。

答案 1 :(得分:2)

这是一个非常好的问题,每个案例都没有一个好的答案。我已经使用并看过各种策略,每种策略都有其优点和对比。

立即加载 - 好吧,这个适用于小型表,以及过滤数据时。当用户导航到其他页面时,不会向数据库发送其他查询。交互开始时的负重成本,以及非常大的内存需求。当典型的是,用户不会滚动整个数据,这是浪费资源。但是,对于小词典,它可能是最好的解决方案。

分页使用限制/偏移(PostgreSQL),rownum(Oracle)或任何关键字。第一页的加 - 高加载时间。减号 - 每个下一页的加载速度较慢,数据库站点的工作量较大。用户通常会看到一个或几个第一页的最佳策略。最糟糕的是,当用户滚动浏览所有数据时。当按主键排序集时,它工作得很好,但是当数据集被过滤并且不按索引排序时,它很糟糕。对于每个页面,它调用过滤(可以使用全表扫描)并在内存中对完整数据集进行排序!

使用数据库游标

滚动。这是最危险的策略。数据库打开游标进行查询,当用户需要下一页时,游标就会被移动。案例的最佳策略,当用户通常滚动所有数据时。报告的首选策略。 Hovewer,在用户交互模式下,它需要数据库连接在交互时锁定。没有其他人可以使用它!与数据库的连接数量有限!在Web应用程序中实现起来也非常困难,您不知道用户是关闭了浏览器还是仍在分析数据 - 您不知道何时释放连接。

答案 2 :(得分:1)

检查此链接有关Oracle中的分页查询。

http://www.oracle.com/technetwork/issue-archive/2007/07-jan/o17asktom-093877.html

基于两个输入参数((1)页码和(2)每页显示的结果数), 您可以使用该查询来获得所需的结果。

同时检查Don Roby在上面指出的查询。它同样好,但我想指出更多oracle特定信息及其处理方式。

答案 3 :(得分:1)

最简单的方法是跟踪您所在的页面,然后通过SQL指定偏移量和限制。在oracle上,这是由indexval和rownum完成的,但这不是标准的,而是其他dbms使用限制。

您还可以独立于数据库并在JDBC之上使用JPA。 Jpa Query类支持setFirstResult和setMaxResults函数用于相同的目的。根据您正在使用的dbms,它将根据您的需要为您执行相应的SQL。

执行select count()有助于确定页数。

答案 4 :(得分:0)

您可以使用limit关键字限制sql查询中的结果集。

从TableName中选择*,其中id> ...按字段名称排序asc limit 50;

从TableName中选择*,其中id< ... order by fieldName desc limit 50;

您需要为后向转发添加一些逻辑。

一种可能的解决方案是获取列表中元素的id,前一页最低,下一页最大,并使用类似上面的sqls

答案 5 :(得分:0)

您需要两个查询。它们将是这些的变体:

  1. 初始查询 从tableName中选择*,其中rownum< = pagesize
  2. 分页查询 从tableName中选择*,其中indexVal>最后一页索引和rownum< = pagesize
  3. 对于初始查询,pagesize将是硬编码数字或变量。对于分页查询,last-page-index必须是传递给查询的变量,pagesize可以是硬编码或变量。

    这些查询假设您没有订购结果。如果您要订购返回值,那么查询将是以下变体:

    1. 初始查询 选择* from(select * from tableName order by blah)其中rownum< = pagesize
    2. 分页查询 选择* from(select * from tableName where indexVal> last-page order by blah)rownum< = pagesize

答案 6 :(得分:0)

对于更通用的解决方案,您应该使用Statement.setFetchSize方法。通过此方法,您可以限制从数据库中提取的记录数。默认情况下,正在获取所有记录。

但是在使用这种方法时你应该谨慎。因为您的结果集应该在网格的生命周期内处于活动状态。

答案 7 :(得分:0)

您可能正在按记录阅读记录。因此,对于每条记录,有两个上下文切换:

  • Java - > Oracle DB(发送记录请求)
  • (Oracle正在运作)
  • Oracle DB - > Java(返回记录)

去查看你的代码,看看你是否可以在for / while循环中找到一些东西,你可以改进它。

还有:我认识一个与Oracle合作很多的人。他告诉我,你可以通过编写智能查询来避免大多数循环。因此,编写一个好的查询是一项巨大的性能提升。