【问题标题】:Confusion with setFetchSize method of Statement Object与 Statement Object 的 setFetchSize 方法混淆
【发布时间】:2014-07-29 15:42:23
【问题描述】:

一开始,我问了this的问题

我通过将fetchSize 设置为Integer.MIN_VALUE 来解决这个问题,但我对此有一些疑问

  1. 当我将 fetchSize 设置为 10 或其他正整数时,它不起作用,将其设置为 Integer.MIN_VALUE 后它起作用,这是为什么?
  2. 如果我们设置负值,那么它会给出非法值错误,但Integer.MIN_VALUE-2147483648 那么为什么它没有给出错误呢?
  3. 此表包含 600 万条记录,我在获取 100 或 200 条记录后关闭了 resultset,然后需要 30-35 秒的时间。
  4. 减少关闭 resultset 的时间的解决方案。

我想在这里添加更多内容 我已经用 MySQL 驱动程序对此进行了测试,它接受Integer.MIN_VALUE 但是当我在 SQL Server 中测试相同的代码时,它会给出错误The fetch size cannot be negative.,如果我将它设置为 10 则它可以工作,它也适用于 Oracle。

【问题讨论】:

  • Integer.MIN_VALUE 可能很棘手。只需查看以下方法调用的结果。 System.out.println(Math.abs(-1));System.out.println(Math.abs(Integer.MIN_VALUE + 1));System.out.println(Math.abs(Integer.MIN_VALUE)); 我并不是说这是您遇到的行为的原因,但它可能是。只能通过调查您正在使用的数据库抽象下的代码来判断。
  • 是的,那是正确的,但那是因为整数溢出
  • 您如何保证 DB 访问抽象下的代码没有做任何与溢出有关的事情?

标签: java prepared-statement resultset


【解决方案1】:

Integer.MIN_VALUE 被 MySQL 驱动程序用作切换到流式结果集模式的信号。它不用作值。请参阅“结果集”下的 the documentation。总结:

默认情况下,ResultSet 被完全检索并存储在内存中。您可以通过设置stmt.setFetchSize(Integer.MIN_VALUE);(结合只进、只读的结果集)告诉驱动程序一次将结果流回一行。

所以这是非常特定于 MySQL 连接器/J 驱动程序的。

至于为什么关闭结果集需要很长时间,同一文档也暗示了这一点:“您必须阅读结果集中的所有行(或关闭它),然后才能发出任何其他查询连接,否则会抛出异常。”
即关闭结果集将首先读取所有剩余的行,然后关闭结果集。而且由于现在逐行读取行,因此可能需要很长时间。 this question 中也描述了这个问题和解决方法/hack。

看来(我还没有测试过)流式结果集有一个替代方案可以做你想做的事(不使用 MySQL 限制子句),它涉及 configuration property useCursorFetch=true 并解释了用法@ 987654324@.

【讨论】:

  • 感谢我的帮助,这是所有有用参考资料的完美答案。
  • 您写道Integer.MIN_VALUE 被用作切换到流媒体模式的信号。然后你写stmt.setFetchSize(Integer.MIN_VALUE); 用于一次获取一行。所以我们有一个相同的东西用于两个不同的目的?如何切换到流模式并一次多行?
  • @Stephane 1) 使用流模式会导致一行一行地获取。 2)你不能,使用替代方案(点击useCursorFetch之后的链接)。
  • 我确实按照链接并实施了解决我的问题的解决方案。我将连接配置为流式传输,获取量为 50。
猜你喜欢
  • 1970-01-01
  • 2011-06-23
  • 1970-01-01
  • 2014-04-15
  • 1970-01-01
  • 1970-01-01
  • 2012-08-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多