【问题标题】:Large result sets with Oracle JDBC, can I turn cursor fetching off? (fetch size issue)使用 Oracle JDBC 的大型结果集,我可以关闭游标获取吗? (获取大小问题)
【发布时间】:2017-06-18 07:34:52
【问题描述】:

我有一个案例,我需要将大约 100 万行有效地加载到内存中进行处理。我为此使用 oracle 和普通 JDBC。

如果我不设置提取大小,则使用默认的 10 的 oracle 驱动程序,这意味着它将需要 100k 往返,这使得性能超级低效。如果我将 fetch size 增加到非常大的值,例如 500k 或 1m,则数据会在大约 5 秒内加载。

不幸的是,我无法将提取大小设置为类似 INT_MAX 的值,因为 oracle 驱动程序会根据提取大小预先分配缓冲区。

我真正想要的是一种强制 JDBC 简单地获取所有行而不使用游标或执行任何增量获取的方法。我想以尽可能节省内存的方式来做到这一点。

有没有办法告诉 oracle 只获取所有数据而不进行任何获取?

【问题讨论】:

  • 这可能是个坏主意。您不是第一个错误地认为他们需要将大量记录集带到服务器端、对其进行处理并将其放回的人。考虑提交较小的块大小或在数据库服务器本身上进行处理。
  • 我绝对推荐尝试在数据库中进行处理。
  • 根据我的经验,将 fetch 大小设置得比 e.g. 10000 并没有真正提高性能。我怀疑如果您超过 500k,您会注意到任何实质性的性能改进(如果说 200 万,它会比 5 秒更快吗?)。并且不要忘记您会将结果集保存在内存中两次(驱动程序和您的应用程序)
  • 在数据库中进行处理在这里没有帮助。我正在为批量下载这些数据实现一个内部网络服务。
  • 我想避免玩为每个查询找出最佳获取大小的游戏。我将查询分为两类:完全适合内存的查询和不适合内存的查询。对于后一类,获取大小是完美的。但我的大部分查询都属于第一类。我想要一种方法来告诉 oracle 只获取所有行而不进行任何不必要的往返。

标签: java sql oracle jdbc


【解决方案1】:

12 驱动程序在获取大小中每列每行分配 15 个字节用于簿记加上实际数据大小。因此,如果您将获取大小设置为 1G,则 12 驱动程序将分配 15GB 用于簿记以及实际数据。因此,根据您有多少内存,您可以将获取大小设置为您有内存支持的任何内容。

12 之前的驱动程序分配了更多的内存,因此获取大小必须更小。

没有办法告诉驱动程序在一次往返中获取所有行。

编辑 2017-03-10:我们已经测试了高达 2G 的行,最近发布的 12.2 驱动程序可以通过 FORWARD_ONLY 结果集处理这个问题。它们将使用 SCROLL_INSENSITIVE 结果集处理多达 1,802,723,000 行。这是一个预期的限制。很明显,这是一台巨大的机器和一个巨大的堆。

【讨论】:

    猜你喜欢
    • 2016-12-26
    • 2015-08-12
    • 2012-01-23
    • 2016-11-09
    • 2013-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-09
    相关资源
    最近更新 更多