A blog on java performance and optimization. On JDBC, Hibernate, caching, algorithms, profiling and anything that can make your code run faster.

 
 
 
 
 
 
 

Sunday, June 21, 2015

JDBC fetch size - commonly forgotten setting

 
JDBC fetch size parameter can significantly reduce the result set fetching time. It can be set on any Statement or PreparedStatement object. Many frameworks like Spring or Hibernate give you very convenient API to do this.

Although this parameter is widely available, I discovered that a lot of projects I have visited did not configure the fetch size and thus was using its default value. Yet, the default value can result in a poor performance on some jdbc drivers.

I want to show you how much you can improve your fetching performance if you adjust the fetch size to your statements. The scale of improvement depends on the driver you use.

Oracle jdbc driver

Assume we have table with 1 million rows and for any reason we have to fetch all records into JVM. How fast you can get all data? What fetch size will Oracle use if you don’t set it explicitly?

Figure 1 - fetching 1M rows with different fetchSize values (local oracle database)

Figure 1 shows fetching times for different fetch size values for Oracle database. In this example database and java application are located on the same machine. I will show later how it looks for a remote database.

Setting Fetch Size with standard JDBC calls

This is how you can set fetch size for given PreparedStatement using JDBC API:

  PreparedStatement stmt = null;
  ResultSet rs = null;
   
  try {
  stmt = conn. prepareStatement("select a, b, c from table");
  stmt.setFetchSize(200);
   
  rs = stmt.executeQuery();
  while (rs.next()) {
  ...
  }
  }

Lets see what happens if fetchSize property is set to 10. When rs.next() is called for first time, the oracle driver fetches first 10 records from database and store them in a memory buffer. So, for next 9 calls to rs.next() records are retrieved from this buffer. After the buffer is fully read, subsequent rs.next()will force driver to fetch a new bunch of rows (10) into the buffer.

So if we want to read 10k rows with fetch size set to 10, the driver will make 1000 round trips to the database using the underlying connection. If we set the fetchSize to 500 the driver will perform only 20 round trips to our database.

Look at Figure 1. Setting fetchSize to 100 gives you a 6 times shorter fetching time then with setting fetchSize to 10. Now, you should know that the default fetchSize for the oracle driver is 10...

Two important comments:

  • fetchSize can be set on each Statement or PreparedStatement or even on ResultSet. By default, ResultSet uses fetchSize of Statement from which is born. The default value for Statement or PreparedStatementis jdbc driver specific
  • fetchSize is only a hint for the driver – the Oracle driver respects this setting, while other drivers may ignore it and fetch all the records at once, for instance.
 

Setting Fetch Size with Spring JdbcTemplate

When using Spring jdbc support you can do this in 2 ways:

Ad hoc JdbcTemplate instance

  JdbcTemplate jdbc = new JdbcTemplate(dataSource);
  jdbc.setFetchSize(200);
   
  jdbc.query("select a, b, c from table",
   
  new RowCallbackHandler() {
  @Override
  public void processRow(ResultSet rs) throws SQLException {
  ...
  }
  }
  );

Shared JdbcTemplate instance

  public class MyJdbcDaoImpl extends JdbcDaoSupport implements MyJdbcDao {
   
  @Override
  protected void initTemplateConfig() {
  getJdbcTemplate().setFetchSize(200);
  }
   
  public MyResult loadAll() {
  final MyResult result = new MyResult();
   
  getJdbcTemplate().query("select a, b, c from table",
   
  new RowCallbackHandler() {
  @Override
  public void processRow(ResultSet rs) throws SQLException {
  ...
  result.add(...);
  }
  }
  );
   
  } // end of loadAll
  }

When implementing a DAO that extends JdbcDaoSupport every call to getJdbcTemplate() returns the same shared JdbcTemplate instance. You can mix this with ad-hoc instances. For example, override initTemplateConfig()to set the default for this DAO but use ad-hoc JdbcTemplate for selected queries.

JDBC fetch size的更多相关文章

  1. SQL Fetch size

    JDBC performance tuning with optimal fetch size February 1, 2009 31 Comments Tuning performance usin ...

  2. hibernate.properties官方属性用例(可用于hibernate.cfg.xml属性参考)

    ######################### Query Language ######################### ## define query language constant ...

  3. hibernate.cfg.xml文件的配置模板和不同数据库的配置參数

    (1)hibernate.cfg.xml文件的配置模板 <?xml version="1.0" encoding="UTF-8"?> <!DO ...

  4. Hibernate配置文件中配置各种数据库的driver、URL

    hibernate.properties ######################### Query Language ######################### ## define qu ...

  5. Hibernate配置文件中配置各种数据库链接

    hibernate.properties ###################### ### Query Language ### ###################### ## define ...

  6. Spark SQL笔记——技术点汇总

    目录 概述 原理 组成 执行流程 性能 API 应用程序模板 通用读写方法 RDD转为DataFrame Parquet文件数据源 JSON文件数据源 Hive数据源 数据库JDBC数据源 DataF ...

  7. hibernate学习(一)配置,导包

    框架的作用 学过javaWeb基础的已经对web层 jsp  servlet   ,service  层  ,dao层的jdbc .DBUtils 有了很深的了解 并编写代码实现某种功能 为了提高开发 ...

  8. JAVA PERSISTENCE API (JPA)

    13.2.1. About JPA The Java Persistence API (JPA) is the standard for using persistence in Java proje ...

  9. java框架之Hibernate(1)-简介及初使用

    简介 hibernate 是一个开源 ORM ( Object / Relationship Mipping ) 框架,它是对象关联关系映射的持久层框架,它对 JDBC 做了轻量级的封装,而我们 ja ...

随机推荐

  1. 课程4:黑马程序员_spring2.5视频教程--视频列表

    \黑马程序员_spring2.5视频教程\01Struts相关基础理论介绍.mp4; \黑马程序员_spring2.5视频教程\02搭建struts开发环境.mp4; \黑马程序员_spring2.5 ...

  2. eclips环境下开发spring boot项目,application.properties配置文件下中文乱码解决方案

    如以上,application.properties文件下中文乱码.发生乱码一般都是由于编码格式不一样导致的. 打开Window-Preferences-General-content Types-T ...

  3. FPN 学习笔记

    通常,利用网络对物体进行检测时,浅层网络分辨率高,学到的是图片的细节特征,深层网络,分辨率低,学到的更多的是语义特征. 1).通常的CNN使用如下图中显示的网络,使用最后一层特征图进行预测 例如VGG ...

  4. Web下文件上传下载的路径问题

    工程结构

  5. JXL导出Excel(只支持xls版本)——(一)

    注意: 导出的后缀是xls可以直接打开,如果导出的后缀是xlsx打开报错,需要手动将名字改为xls才可以打开.也就是JXL不可以导出xlsx的excel. Jar包

  6. C# ASP.NET MVC 配置允许跨域访问

    在web.config文件中的 system.webServer 节点下 增加如下配置 <httpProtocol> <customHeaders> <add name= ...

  7. STM32F103X datasheet学习笔记---USART

    1.前言 通用同步异步收发器(USART)提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换. USART利用分数波特率发生器提供宽范围的波特率选择. 它支持同步 ...

  8. Linux串口—struct termios结构体【转】

    转自:https://blog.csdn.net/yemingzhu163/article/details/5897156 一.数据成员 termios 函数族提供了一个常规的终端接口,用于控制非同步 ...

  9. WPF中添加Winform用户自定义控件

    过程:创建WPF工程->创建Winform用户自定义控件工程->WPF中引用控件->添加到Xaml页面 1.首先在WPF工程的解决方案上右击选择添加新建项目: 选择Windows窗体 ...

  10. maven项目提示web.xml is missing或红色感叹号

    1.web.xml is missing and <failOnMissingWebXml> is set to true 提示信息应该能看懂.也就是缺少了web.xml文件,<fa ...