You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何执行ResultSet获取大小代码后,迭代耗时大幅降低?

为什么执行ResultSet滚动操作后迭代速度暴增?

先把你的代码贴出来方便大家理解:

int size =0; 
if (rs != null) { 
    rs.last(); 
    size = rs.getRow(); 
    rs.beforeFirst(); 
}

// 后续迭代逻辑
while (rs.next()) { 
    // 处理每行数据
}

你观察到的迭代耗时从500ms骤降到50ms,核心原因是这段滚动操作彻底改变了JDBC驱动加载结果集的方式:

  • 默认的流式加载拖慢了速度:大多数JDBC驱动在处理默认的TYPE_FORWARD_ONLY类型ResultSet时,会用流式获取的策略——不会一次性把所有查询结果拉到客户端内存,而是每次只取一小批数据(比如10行,具体由驱动的fetchSize参数控制)。当你调用rs.next()迭代时,每用完当前批次的数据,就得和数据库再通信一次去拉取下一批,频繁的网络交互就是初始迭代慢的元凶。

  • 滚动操作触发了全量缓存:当你调用rs.last()时,驱动必须定位到结果集的最后一行,这就逼着它把所有查询结果一次性加载到客户端的内存里(不然根本不知道最后一行在哪)。之后调用rs.beforeFirst()回到结果集开头,后续的rs.next()就直接从本地内存读数据,完全不用再跟数据库打交道,速度自然就上去了。

还要补充几个关键细节:

  • 这种操作能生效的前提是你的ResultSet是可滚动类型(比如TYPE_SCROLL_INSENSITIVE或TYPE_SCROLL_SENSITIVE)——如果你的代码能执行rs.last(),说明你创建Statement/PreparedStatement时指定了这个类型。
  • 别盲目用这种方法:如果结果集特别大(比如几十万行),全量加载会吃掉大量客户端内存,搞不好会触发OutOfMemoryError。如果只是想知道结果集大小,不如单独执行SELECT COUNT(*) FROM ...查询,避免加载全量数据。

内容的提问来源于stack exchange,提问作者Giacomo Chiavarini

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:42:58