0

0

如何配置Oracle JDBC的Fetch Size_提升大结果集查询的网络传输性能

P粉602998670

P粉602998670

发布时间:2026-03-18 06:11:22

|

179人浏览过

|

来源于php中文网

原创

Oracle的setFetchSize()常无效,因驱动默认行缓冲且服务端忽略请求,须显式启用oracle.jdbc.defaultRowPrefetch或在executeQuery()前设置;仅对ResultSet生效,受驱动版本、数据类型(如LONG)、网络与内存影响,需合理配置并验证。

为什么 setFetchSize() 在 Oracle JDBC 里经常没效果

oracle 的 setfetchsize() 默认不生效,不是你代码写错了,而是驱动默认用「行缓冲」而非「列缓冲」,且服务端会忽略客户端的 fetch size 请求——除非显式启用 oracle.jdbc.defaultrowprefetch 或在 statement 上主动设置。更关键的是:它只对 resultset 生效,对 preparedstatement 的批量插入/更新无效。

常见错误现象:setFetchSize(1000) 后用 Wireshark 抓包,发现每次仍只传几十行;或者日志里看到 ORA-01000: maximum open cursors exceeded,其实是 fetch size 太小导致频繁往返、游标堆积。

  • 必须在 executeQuery() 前调用 setFetchSize(),之后调用无效
  • 连接 URL 加 ?oracle.jdbc.defaultRowPrefetch=1000 可全局生效,但无法动态调整
  • Oracle 12c+ 支持服务端 hint /*+ FETCH_SIZE(1000) */,但需配合驱动参数 oracle.jdbc.useFetchSizeWithLongColumn=true
  • 如果查询含 LONGXMLTYPE 或大 BLOB,fetch size 会被自动降级为 1,得加 useFetchSizeWithLongColumn=true 强制启用

PreparedStatement 的 setFetchSize() 怎么设才真正起作用

很多人在 PreparedStatement 上调 setFetchSize() 却发现没变化,是因为 Oracle 驱动对预编译语句的 fetch size 处理更保守:它只在执行 executeQuery() 时读取当前值,且受连接属性 defaultRowPrefetch 覆盖。换句话说,代码里设了,但驱动可能直接无视。

使用场景:分页导出百万级订单数据,不想 OOM,也不愿用 ROWNUM 分页(性能差)。

  • 优先在获取 PreparedStatement 后、executeQuery() 前立即调用 setFetchSize(500)
  • 避免复用同一 PreparedStatement 多次查询不同 SQL —— fetch size 设置会残留,影响下一次
  • 若用 HikariCP 等连接池,确保连接池未重置 Statement 属性(Hikari 默认不会,但某些老版本 Druid 会)
  • 验证是否生效:开启 JDBC 日志(oracle.jdbc.Trace=true),搜索 fetchSizerowsFetched

Fetch Size 设太大反而变慢?看网络和内存怎么博弈

设成 10000 不一定比 100 快。Oracle 客户端一次从服务端拉取的数据,会先缓存在 JVM 堆内,再逐行交给应用。fetch size 过大,单次网络包超 MTU,触发 TCP 分片;JVM 一次性分配大数组,GC 压力陡增;服务端 PGA 内存占用也会上升,可能被 DBA 杀掉。

性能影响关键点:网络延迟高(比如跨机房查库)、结果集字段多(尤其含 VARCHAR2(4000))、JVM 堆小于 2G。

提客AI提词器
提客AI提词器

「直播、录课」智能AI提词,搭配抖音直播伴侣、腾讯会议、钉钉、飞书、录课等软件等任意软件。

下载
  • 建议起始值用 100 ~ 500,再按实际 RT 和 GC 日志调整
  • jstat -gc <pid> 观察 YGCT 是否突增;用 netstat -s | grep -i "retransmit" 看重传率
  • Oracle 服务端参数 SQLNET.SEND_TIMEOUTRECV_TIMEOUT 要大于 fetch 大块数据的预期耗时,否则直接断连
  • 别迷信“越大越好”——实测过 fetch size=5000 时吞吐反降 30%,因服务端 PGA 分配失败退回到单行模式

Spring JdbcTemplate 怎么安全透传 Fetch Size

Spring 的 JdbcTemplate 默认把 setFetchSize() 当作 hint,不保证传递。它内部用 Connection.prepareStatement() 创建语句,但没暴露接口让你干预 Statement 实例。直接在回调里设,往往太晚。

正确做法不是改 Spring 源码,而是绕过封装,自己管 Statement 生命周期。

  • JdbcTemplate.getDataSource().getConnection() 拿原生连接,手动创建 PreparedStatement,再设 setFetchSize()
  • 或实现 PreparedStatementSetter,并在 setValues() 里强转 PreparedStatementOraclePreparedStatement(需引入 ojdbc8 依赖)
  • 千万别用 @Transactional 包裹手动连接操作——事务上下文会丢失
  • 如果必须用 query() 方法,可传入自定义 ResultSetExtractor,并在其 extractData() 内通过 rs.getStatement().getFetchSize() 反查是否生效

最常被忽略的一点:Oracle 驱动版本低于 19.3 时,即使代码全对,setFetchSize() 在某些 JDK 11+ 场景下也会静默失效——得升级 ojdbc 或加 JVM 参数 -Doracle.jdbc.useFetchSizeWithLongColumn=true 强制唤醒。

数码产品性能查询
数码产品性能查询

该软件包括了市面上所有手机CPU,手机跑分情况,电脑CPU,电脑产品信息等等,方便需要大家查阅数码产品最新情况,了解产品特性,能够进行对比选择最具性价比的商品。

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

1135

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

340

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

381

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2278

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

380

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

1764

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

588

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

441

2024.04.29

抖漫入口地址合集
抖漫入口地址合集

本专题整合了抖漫入口地址相关合集,阅读专题下面的文章了解更多详细地址。

17

2026.03.17

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号