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. Maven入门-运行struts项目进行测试(三)

    maven运行struts项目进行测试: 在入门二中已经导入struts的jar包. 此时的pom.xml文件 <project xmlns="http://maven.apache. ...

  2. 【黑客免杀攻防】读书笔记2 - 免杀与特征码、其他免杀技术、PE进阶介绍

    第3章 免杀与特征码 这一章主要讲了一些操作过程.介绍了MyCCL脚本木马免杀的操作,对于定位特征码在FreeBuf也曾发表过类似工具. VirTest5.0特征码定位器 http://www.fre ...

  3. 使用Navicat Premium对mssql2008r2授权用户

    使用Navicat Premium操作mssql2008r2数据库 比如需要对某个特定的数据tes添加一个管理员em,并且这个管理员只能对test这个数据库进行操作 使用sa连接数据库 1.新建一个登 ...

  4. windows下搭建eclipse关于python的开发环境及初始化参数配置

    1.安装jdk 因为eclipse是java开发的,运行eclipse程序需要安装jdk 安装jdk以后需要配置java_home环境变量 2.安装python2.7(比较简单,此处略) 3.下载ec ...

  5. centos6中iptables单机网络防火墙的使用

    概述: iptables:基于软件的形式实现的一种防火墙的软件程序 Firewall:工作在主机或网络边缘,对进出的报文按事先定义的规则进行检查,并且由匹配到的规则进行处理的一组硬件或软件,甚至可能是 ...

  6. jquery学习集合

    跳转网页:$(location).attr('href', '/index');

  7. Ex 6_23 一个生产系统共包含n个顺序执行的阶段..._第七次作业

  8. javascript 类型比较方法

    不要使用new Number().new Boolean().new String()创建包装对象: 用parseInt()或parseFloat()来转换任意类型到number: 用String() ...

  9. cf789d 图论计数,自环闭环

    一开始没有思路,以为要判联通块. 其实不是判断联通块,而是判断边是否连在一起,没有连边的点可以忽略不计 /* 分情况讨论: 1.忽略自环,那么要取出两条相连的普通变作为只经过一次的边 2.一条自环,一 ...

  10. 性能测试三十二:监控之Java线程监控

    线程的五种状态 * 新建:new * 运行:runnable * 等待:waitting(无限期等待),timed waitting(限期等待) * 阻塞:blocked * 结束:terminate ...