我的数据网格中包含超过10k行的页面,因此在首次加载时速度很慢。什么是解决这个问题的最佳方法。我已经读过JDBC分页是这种问题的常用解决方案,但有些人说使用SQL ROWNUM是一个更简单的解决方案,所以我想先问一下。
如果您认为分页是最好的解决方案,请给我一些关于如何继续讨论的指示(链接到实现等)
答案 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)
您需要两个查询。它们将是这些的变体:
对于初始查询,pagesize将是硬编码数字或变量。对于分页查询,last-page-index必须是传递给查询的变量,pagesize可以是硬编码或变量。
这些查询假设您没有订购结果。如果您要订购返回值,那么查询将是以下变体:
答案 6 :(得分:0)
对于更通用的解决方案,您应该使用Statement.setFetchSize方法。通过此方法,您可以限制从数据库中提取的记录数。默认情况下,正在获取所有记录。
但是在使用这种方法时你应该谨慎。因为您的结果集应该在网格的生命周期内处于活动状态。
答案 7 :(得分:0)
您可能正在按记录阅读记录。因此,对于每条记录,有两个上下文切换:
去查看你的代码,看看你是否可以在for / while循环中找到一些东西,你可以改进它。
还有:我认识一个与Oracle合作很多的人。他告诉我,你可以通过编写智能查询来避免大多数循环。因此,编写一个好的查询是一项巨大的性能提升。