我的编程空间,编程开发者的网络收藏夹
学习永远不晚

JDBC读取数据优化-fetch size

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

JDBC读取数据优化-fetch size

最近由于业务上的需求,一张旧表结构中的数据,需要提取出来,根据规则,导入一张新表结构中,开发同学写了一个工具,用于实现新旧结构的transformation,


实现逻辑简单,就是使用jdbc从A表读出数据,做了一些处理,再存入新表B中,发现读取旧表的操作,非常缓慢,无法满足要求。

读取数据的示例代码,

conn = getConnection();
long start = System.currentTimeMillis();
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
long mid_end = System.currentTimeMillis();
while (rs.next()) {
    list.add(rs.getString(1));
}
long end = System.currentTimeMillis();
rs.close();
System.out.println("Interval1=" + (mid_end - start));
System.out.println("Interval2=" + (end - mid_end));

SQL语句读取10000条记录,其中,

Interval1=160ms
Interval2=29252ms

执行executeQuery()这个SQL检索的时间为160毫秒。

执行10000次rs.next以及rs.getString(1)的用时约为30秒,平均1条记录3毫秒。

如何才能提高读取的效率?

上面读取10000条记录,每一次rs.next时间只有3毫秒,但是由于需要10000次,所以才需要30秒,我们可以猜测,是否有可能每一次rs.next的执行,均需要和数据库交互,因为如果仅是字符串操作,不应该是这个数量级。

看一下官方文档的描述,《Database JDBC Developer's Guide》有一节介绍了Fetch Size,

By default, when Oracle JDBC runs a query, it retrieves a result set of 10 rows at a time from the database cursor. This is the default Oracle row fetch size value. You can change the number of rows retrieved with each trip to the database cursor by changing the row fetch size value.


Standard JDBC also enables you to specify the number of rows fetched with each database round-trip for a query, and this number is referred to as the fetch size. In Oracle JDBC, the row-prefetch value is used as the default fetch size in a statement object. Setting the fetch size overrides the row-prefetch setting and affects subsequent queries run through that statement object.


Fetch size is also used in a result set. When the statement object run a query, the fetch size of the statement object is passed to the result set object produced by the query. However, you can also set the fetch size in the result set object to override the statement fetch size that was passed to it.


Changes made to the fetch size of a statement object after a result set is produced will have no affect on that result set.

JDBC默认每执行一次检索,会从游标中提取10行记录,10就是默认的row fetch size值,通过设置row fetch size,可以改变每次和数据库交互,提取出来的记录行总数。需要注意的是,需要在获得检索结果集之前,设置fetch size,否则就是无效。

可以使用如下方法设置,

Setting the Fetch Size

The following methods are available in all Statement, PreparedStatement, CallableStatement, and ResultSet objects for setting and getting the fetch size:

  • void setFetchSize(int rows) throws SQLException

  • int getFetchSize() throws SQLException

简单来讲,Fetch相当于读缓存,默认Fetch Size值是10,读取10000条记录,一次数据库交互,即rs.next的操作,ResultSet会一次性从数据库服务器,得到10条记录,下次执行rs.next,就直接使用内存读取,不用和数据库交互了,但总计需要有1000次交互,如果使用setFetchSize设置Fetch Size为10000,则只需要一次数据库交互,本地缓存10000条记录,每次执行rs.next,只是内存操作,不会有数据库网络消耗,效率就会高些。但需要注意的是,Fetch Size值越高则占用内存越高,要避免出现OOM错误。

方案1:


rs = ps.executeQuery();
rs.setFetchSize(10000);

即在执行ps.executeQuery()之后,对rs设置值10000,统计如下,

执行executeQuery()这个SQL检索的时间为174毫秒。

执行10000次rs.next以及rs.getString(1)的用时约为190毫秒。

相比之前执行10000次rs.next,用了30秒,提高了将近150倍。



方案2:


ps = conn.prepareStatement(sql);
ps.setFetchSize(10000);

即在执行conn.prepareStatement(sql)之后,执行ps.executeQuery()之前,对rs设置值为10000范围,统计如下,

执行executeQuery()这个SQL检索的时间为267毫秒。

执行10000次rs.next以及rs.getString(1)的用时约为87毫秒。

相比方案2,总用时几乎一致,但SQL执行和rs.next遍历的用时,有些区别。


针对方案1,

After you have run the query, you can call  setFetchSize  on the result set object to override the statement object fetch size that was passed to it. This will affect any subsequent trips to the database to get more rows for the original query, as well as affecting any later refetching of rows.

执行查询之后,对结果集设置setFetchSize,会影响任何接下来的数据库交互过程获得更多的记录行数,以及之后的fetch提取。

针对方案2,

To set the fetch size for a query, call  setFetchSize  on the statement object prior to running the query. If you set the fetch size to N, then N rows are fetched with each trip to the database.

执行查询之前,设置setFetchSize,表示每次和数据库交互,得到记录行数。

综上所述,建议执行SQL之前,设置此值,效率提升最高。

对于PrepareStatement、ResultSet和Statement,均有这一个方法,有一点出入的,就是默认值设置(0),从代码中使用getFetchSize(),得到的值均为10,不知道是我理解错了,还是有其他含义?欢迎各位指教。

PrepareStatement

  • setFetchSize

    
    
    void setFetchSize(int rows)
    
              throws SQLException

    Gives the JDBC driver a hint as to the number of rows that should be fetched from the database when more rows are needed for  ResultSet objects generated by this  Statement . If the value specified is zero, then the hint is ignored. The default value is zero.

    • Parameters:

    • rows - the number of rows to fetch

    • Throws:

    • SQLException - if a database access error occurs, this method is called on a closed Statement or the condition rows >= 0 is not satisfied.

    • Since:

    • 1.2

    • See Also:

    • getFetchSize()

ResultSet

  • setFetchSize

    
    
    void setFetchSize(int rows)
    
              throws SQLException

    Gives the JDBC driver a hint as to the number of rows that should be fetched from the database when more rows are needed for this  ResultSet  object. If the fetch size specified is zero, the JDBC driver ignores the value and is free to make its own best guess as to what the fetch size should be.  The default value is set by the  Statement  object that created the result set.  The fetch size may be changed at any time.

    • Parameters:

    • rows - the number of rows to fetch

    • Throws:

    • SQLException - if a database access error occurs; this method is called on a closed result set or the condition rows >= 0 is not satisfied

    • Since:

    • 1.2

    • See Also:

    • getFetchSize()

Statement

  • setFetchSize

    
    
    void setFetchSize(int rows)
    
              throws SQLException

    Gives the JDBC driver a hint as to the number of rows that should be fetched from the database when more rows are needed for  ResultSet objects generated by this  Statement . If the value specified is zero, then the hint is ignored. The default value is zero.

    • Parameters:

    • rows - the number of rows to fetch

    • Throws:

    • SQLException - if a database access error occurs, this method is called on a closed Statement or the condition rows >= 0 is not satisfied.

    • Since:

    • 1.2

    • See Also:

    • getFetchSize()


总结:

1. Fetch相当于读缓存,如果使用setFetchSize设置Fetch Size为10000,本地缓存10000条记录,每次执行rs.next,只是内存操作,不会有数据库网络消耗,效率就会高些。但需要注意的是,Fetch Size值越高则占用内存越高,要避免出现OOM错误。

2. 建议执行SQL语句之前设置,即ps.executeQuery();之前使用setFetchSize()函数设置。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

JDBC读取数据优化-fetch size

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Redis读取大数据量的优化措施有哪些

使用批量读取:尽量使用一次性读取多个数据项,而不是多次单独读取,以减少网络开销和提高读取效率。使用Pipeline:通过Pipeline将多个读取请求打包成一个请求发送给Redis服务器,减少网络往返次数,提高读取性能。使用合适的数据结构:
Redis读取大数据量的优化措施有哪些
2024-05-07

什么是 JDBC Blob 数据类型如何存储和读取其中的数据

JDBC Blob(Binary Large Object)是一种用于存储大型二进制数据的数据类型,比如图片、音频、视频等。在数据库中,Blob数据类型存储的是二进制数据的指针,而不是实际的数据。实际的数据可以通过Java程序进行存储和读取
2023-10-10

什么是 JDBC Blob 数据类型?如何存储和读取其中的数据?

BLOB 是二进制大对象,可以容纳可变数量的数据,最大长度为 65535 个字符。它们用于存储大量二进制数据,例如图像或其他类型的数据。文件。定义为 TEXT 的字段也保存大量数据。两者之间的区别在于,存储数据的排序和比较在 BLOB 中区
2023-10-22

阿里云数据库读写性能优化

随着大数据时代的到来,数据库已经成为企业信息化建设中的重要组成部分。在海量数据的处理中,读写性能的优化已经成为关键。本文将详细介绍阿里云数据库的读写性能优化方法和技巧。一、阿里云数据库简介阿里云数据库是阿里巴巴集团推出的数据库服务,旨在提供稳定、安全、高效的数据存储和处理能力。阿里云数据库支持多种数据库引擎,如M
阿里云数据库读写性能优化
2023-12-15

kettle怎么优化抽取数据速度

要优化抽取数据速度,可以考虑以下几个方面:1. 使用更高效的数据结构:使用更适合存储和快速访问的数据结构,如使用哈希表而不是列表。2. 使用索引:对于需要频繁访问的数据,可以创建索引来加快数据的检索速度。3. 避免不必要的数据转换:尽量减少
2023-09-20

Oracle Index与数据库的读写分离优化

Oracle Index是数据库中一种重要的数据结构,用于加快数据库的查询速度。通过创建合适的Index,可以大大减少查询的时间,提高数据库的性能。但是在实际应用中,Index也会带来一些问题,比如Index的更新会增加写操作的开销。为了解
Oracle Index与数据库的读写分离优化
2024-08-14

MySQL INSERT锁与数据库读写分离优化

在MySQL中,INSERT操作会涉及到行级锁和表级锁。当使用INSERT语句向某个表中插入数据时,会对表或者索引进行加锁,以确保数据的一致性和完整性。在插入大量数据时,可能会出现锁竞争和性能瓶颈的情况。为了优化数据库的性能,可以考虑使用
MySQL INSERT锁与数据库读写分离优化
2024-08-19

React数据获取与性能优化详解

这篇文章主要为大家介绍了React数据获取与性能优化方法示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-11-13

python中Pandas读取数据文件的优点是什么

这篇文章给大家分享的是有关python中Pandas读取数据文件的优点是什么的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1、优点Pandas 提供了多种常用文件格式的读写函数,以上各种情况都能一行代码搞定。Pa
2023-06-15

PHP与MySQL索引的数据读取和查询优化的性能优化策略及其对性能的影响

摘要:在PHP与MySQL开发中,高效的数据读取和查询优化对于提升应用程序的性能至关重要。本文将介绍一些性能优化策略,并通过具体的代码示例来说明其对性能的影响。索引的基本概念索引是一种数据结构,用于加速数据库的数据检索。在MySQL中,常见
2023-10-21

SpringBoot+thymeleaf+Echarts+Mysql怎么实现数据可视化读取

这篇文章主要介绍了SpringBoot+thymeleaf+Echarts+Mysql怎么实现数据可视化读取的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇SpringBoot+thymeleaf+Echarts
2023-06-30

如何使用MySQL MVCC 优化数据库读写操作?

如何使用MySQL MVCC 优化数据库读写操作?摘要:随着数据库应用的不断增加,数据库的性能以及并发访问的效率成为开发者关注的重点。MySQL的MVCC(多版本并发控制)是一种有效的优化数据库读写操作的机制,本文将介绍MVCC的概念、原理
2023-10-22

编程热搜

目录