当前位置: 首页 > 知识库问答 >
问题:

JDBC分页:特定于供应商的sql与结果集获取大小

解高昂
2023-03-14

互联网上有很多关于使用JDBC/迭代巨大结果集进行分页的不同教程。因此,到目前为止,我基本上找到了很多方法:

> < li >供应商特定的sql < li >可滚动的结果集(?) < li >将普通结果集保存在内存中,仅在必要时映射行(使用fetchSize) < blockquote > < p >结果集提取大小(显式设置或默认等于传递给它的语句提取大小)决定了在该结果集的任何后续数据库访问中检索的行数。这包括完成原始查询仍然需要的任何行程,以及将数据重新提取到结果集中的任何操作。可以显式或隐式地重新提取数据,以更新滚动敏感或滚动不敏感/可更新的结果集。

抱歉搞砸了所有这些,但我需要有人帮我清理一下。我有一个简单的任务,服务消费者要求带有pageNumber和pageSize的结果。看起来我有两个选项:

  1. 使用特定于供应商的sql
  2. 将连接/语句/结果集保存在内存中,并依赖jdbc fetchSize

在后一种情况下,我使用rxJava-jdbc,如果您查看生产者实现,它保存结果集,然后您所做的就是调用请求(long n)并处理另外n行。当然,所有内容都隐藏在rxJava的可观察建议下。我不喜欢这种方法的地方在于,您必须在不同的服务调用之间保存结果集,并且如果客户端忘记耗尽或关闭它,则必须清除该结果集。(注意:这里的结果集是java ResultSet类,不是实际数据)

那么,推荐的分页方法是什么?与保持连接相比,供应商特定的 sql 是否被视为慢?

我使用的是oracle,不建议将RollappableResultSet与大型结果集一起使用,因为它在客户端缓存整个结果集数据。证明

共有3个答案

卫景明
2023-03-14

ScrollableResultSet缓存客户端的结果——这需要内存资源。但例如PostgreSQL默认情况下这样做,没有人抱怨。一些数据库只是使用客户端的内存来保存整个结果集。在大多数情况下,数据库必须处理更多的数据才能重新评估查询。此外,您通常拥有比数据库实例更多的客户端。

还请注意,Hibernate实现的查询重新执行(使用rownum)不能保证正确(一致)的结果。如果在执行之间修改数据,则使用默认隔离级别。

这确实取决于用例。更改最大连接数和打开游标的Oracle init参数需要重新启动数据库。因此,只有在可以预测(并发)用户数量时,才能使用ScrollableResultSet和游标。

张唯
2023-03-14

有许多方法,因为有许多不同的用例。

您真的希望用户获取结果集的每个页面吗?或者,如果他们感兴趣的数据不存在,他们更有可能获取第一页或第二页并尝试其他内容。例如,如果你是谷歌,你可以很有信心,人们会从第一页看到结果,少数人会从第二页看到结果。而一小部分结果会从第三页看到。在这种情况下,使用特定于供应商的代码来请求一页数据并仅在用户请求时为下一页运行该代码是非常有意义的。另一方面,如果您希望用户获取结果的最后一页,那么为每个页面运行单独的查询将比运行单个查询并执行多个获取更昂贵。

用户需要将查询保持打开状态多长时间?有多少个并发用户?如果您正在构建一个有几十个用户可以访问的内部应用程序,并且您希望用户将游标保持打开几分钟,那么这可能是合理的。如果您尝试构建一个应用程序,该应用程序将有数千个用户在几个小时内对结果进行分页,则保持资源分配是一个坏主意。如果您的用户确实是要尽快获取数据并在循环中处理数据的计算机,那么具有多个提取的单个ResultSet就更有意义了。

没有遗漏任何一行/每一行只显示一次/页面之间的结果一致有多重要?从一个游标进行多次提取可以确保结果中的每一行都只显示一次。单独的分页查询可能不会——新数据可能已在正在执行的查询之间添加或删除,排序可能不完全确定,等等。

夹谷野
2023-03-14

保持资源无限期打开通常是一件坏事。例如,数据库会为您创建一个游标来获取获取的行。该游标和其他资源将保持打开状态,直到您关闭结果集。您并行执行的查询越多,占用的资源就越多,并且在某个时候,由于资源池耗尽,数据库将拒绝进一步的请求(例如,一次可以打开的游标数量有限)。

例如,Hibernate使用特定于供应商的SQL来获取“页面”,我会这样做。

 类似资料:
  • JDBC ResultSet是否支持分页?或者我应该通过缓存结果集来在我的服务中实现内部分页。我寻找这样一个解决方案的原因是-我不允许更改表结构。如果允许,我可以有一个自动增量列,然后使用该列和限制上的子句获取数据。

  • JDBC结果集是否在一次SQL查询的网络调用中提取所有数据?考虑查询< code > select * from table where timestamp

  • 问题内容: 考虑这个SQL查询 该查询将仅在字段中返回一个值。 有没有一种方法可以在不使用a并指向返回数组的第一个值的情况下获取该值? 问题答案: 将允许您直接从结果集中提取值,而不必使用 提取 方法。这是一个非常简单的示例,说明如何使用它来获取单个值: 该函数有三个参数。第一个是结果集本身,第二个是行索引,第三个是字段索引。我只使用前两个参数,因为第三个参数默认为0,即返回第一个字段。

  • JDBC是否有专门从Hive查询放入ResultSet的最大行数?我说的不是获取大小或分页,而是ResultSet中返回的总行数。 如果我错了,请更正,但获取大小设置了jdbc在数据库中每次传递时要处理的行数,并将适当的响应插入到结果集中。当它遍历了表中的所有记录后,它将结果集返回给Java代码。我问返回到Java代码的行数是否有限制。 如果它没有最大行数,则该类是否有任何固有的内容可能导致某些记

  • 问题内容: 我有连接3个表的SQL查询,一个表只是将其他两个表连接起来的多对多表。我使用Spring JDBCResultSetExtractor将ResultSet转换成我的Objects,看起来像这样: ResultSetExtractor实现如下所示: 无需分页即可正常工作。 但是,我需要对这些结果进行分页。我通常的做法是将其添加到查询中,例如: 但是,由于此查询具有联接,因此当我限制结果数

  • 主要内容:ResultSet类型,ResultSet的并发性,浏览结果集,查看结果集,更新结果集SQL语句执行后从数据库查询读取数据,返回的数据放在结果集中。 语句用于从数据库中选择行并在结果集中查看它们的标准方法。 接口表示数据库查询的结果集。 对象维护指向结果集中当前行的游标。 术语“结果集”是指包含在对象中的行和列数据。 接口的方法可以分为三类: 浏览方法:用于移动光标。 获取方法:用于查看光标指向的当前行的列中的数据。 更新方法:用于更新当前行的列中的数据。 然后在基础数据库中更新数