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. 【TensorFlow】tf.nn.softmax_cross_entropy_with_logits的用法

    在计算loss的时候,最常见的一句话就是 tf.nn.softmax_cross_entropy_with_logits ,那么它到底是怎么做的呢? 首先明确一点,loss是代价值,也就是我们要最小化 ...

  2. java 多线程三

    java 多线程一 java 多线程二 java 多线程三 java 多线程四 注意到 java 多线程一 中 MyThread2 运行结果出现0.-1,那是因为在操作共享数据时没有加锁导致. 加锁的 ...

  3. python 退出程序的方式

    python程序退出方式[sys.exit() os._exit() os.kill() os.popen(...)] 知乎说明 http://www.zhihu.com/question/21187 ...

  4. UML和模式应用2: 迭代、进化和敏捷

    1.前言 本章主要介绍迭代.敏捷开发及UP(统一过程)的基本概念 2.基本术语 Items Note 软件开发过程 描述了构造.部署及维护软件的方式 迭代开发 是一种软件开发过程的生命周期模型,依赖短 ...

  5. flask_restplus(1)- 未完成

    快速开始 本指南假设您对Flask有一定的了解,并且您已经安装了Flask和Flask- restplus.如果没有,则按照安装部分中的步骤操作. 初始化 与其他所有扩展一样,您可以使用应用程序对象初 ...

  6. Java使用google开源工具Thumbnailator实现图片压缩

    <dependency> <groupId>net.coobird</groupId> <artifactId>thumbnailator</ar ...

  7. 深度学习Bible学习笔记:第一章 前言

    写在前面:请务必踏踏实实看书,结合笔记或视频来理解学习,任何技术,啃砖头是最扎实最系统的,为避免知识碎片化,切忌抛却书本的学习!!! 一 什么是深度学习 1 关于AI: AI系统必须具备从原始数据提取 ...

  8. VS-常用的快捷键-总结

    1: 快速添加引用 === Shift+Alt+F10; 也可用于实现抽象类 2: 直接添加属性 ===prop+Tab+Tab; 3: 根据字段添加属性 === Ctrl +r+e; 4: 格式化代 ...

  9. Angular2学习(一)

    Angular2的新特性: angular2的核心: 模块.组件.元数据.模板.数据绑定.服务.指令.依赖注入.模块. 组件:层层嵌套,形成组件树.父子组件沟通有输入和输出接口 组件包含JavaScr ...

  10. ERP完善合同起草(二十八)

    前端的代码: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="CRMCont ...