首页  >  问答  >  正文

了解 SQL Server JDBC 驱动程序中 Statement.setFetchSize(nSize) 方法的功能

<p>我有一个非常大的表,每天都有数百万条记录,每天结束时我都会提取前一天的所有记录。我这样做是这样的:</p> <pre class="brush:php;toolbar:false;">String SQL = "select col1, col2, coln from mytable where timecol = yesterday"; Statement.executeQuery(SQL);</pre> <p>问题是这个程序需要大约 2GB 内存,因为它将所有结果放入内存中然后对其进行处理。 </p> <p>我尝试设置 <code>Statement.setFetchSize(10)</code> 但它从操作系统中获取完全相同的内存,没有任何区别。我为此使用<em>Microsoft SQL Server 2005 JDBC 驱动程序</em>。</p> <p>是否有任何方法可以像 Oracle 数据库驱动程序那样以小块形式读取结果,当执行查询时仅显示几行,并且当您向下滚动时会显示更多结果?</p>
P粉463811100P粉463811100440 天前555

全部回复(1)我来回复

  • P粉186897465

    P粉1868974652023-08-28 10:02:56

    在 JDBC 中,setFetchSize(int) 方法对于 JVM 内的性能和内存管理非常重要,因为它控制从 JVM 到数据库的网络调用数量以及相应的数据量。用于结果集处理的 RAM。

    本质上,如果调用 setFetchSize(10) 并且驱动程序忽略它,则可能只有两个选项:

    1. 尝试使用不同的 JDBC 驱动程序来支持获取大小提示。
    2. 查看 Connection 上特定于驱动程序的属性(创建 Connection 实例时的 URL 和/或属性映射)。

    RESULT-SET 是为响应查询而在数据库上编组的行数。 ROW-SET 是每次从 JVM 调用到 DB 时从 RESULT-SET 中提取的行块。 这些调用的数量以及处理所需的 RAM 取决于 fetch-size 设置。

    因此,如果 RESULT-SET 有 100 行并且 fetch-size 为 10, 在任何给定时间,都会有 10 个网络调用来检索所有数据,使用大约 10*{row-content-size} RAM。

    默认的 fetch-size 是 10,这个值相当小。 在发布的案例中,驱动程序似乎忽略了获取大小设置,在一次调用中检索所有数据(需要大量 RAM,最佳最小网络调用)。

    ResultSet.next() 下发生的情况是,它实际上并没有从 RESULT-SET 中一次获取一行。它从(本地)ROW-SET 获取该数据,并在本地客户端上的数据耗尽时从服务器获取下一个 ROW-SET(不可见)。

    所有这些都取决于驱动程序,因为设置只是一个“提示”,但在实践中我发现这就是许多驱动程序和数据库的工作原理(在许多版本的 Oracle、DB2 和 MySQL 中得到验证)。

    回复
    0
  • 取消回复