JDBC優化之Batch、Fetch

壹頁書發表於2013-12-11
Batch和Fetch兩個特性非常重要。
Batch相當於JDBC的寫緩衝,Fetch相當於讀緩衝。

  1. import java.sql.Connection;
  2. import java.sql.DriverManager;
  3. import java.sql.PreparedStatement;
  4. import java.sql.ResultSet;
  5. import java.sql.SQLException;
  6. import java.util.ArrayList;
  7. import java.util.List;

  8. public class Test {
  9.     private static int _1W = 10000;
  10.     private static List<String> list = new ArrayList<String>(100 * _1W);
  11.     static {
  12.         for (int i = 0; i < 10 * _1W; i++) {
  13.             list.add(String.valueOf(i));
  14.         }
  15.     }

  16.     public static void main(String[] args) throws ClassNotFoundException, SQLException {
  17.         long start = System.currentTimeMillis();
  18.         fetchRead();
  19.         long end = System.currentTimeMillis();
  20.         System.out.println((end - start) + "ms");
  21.     }

  22.     public static void batchWrite() throws SQLException, ClassNotFoundException {
  23.         // 1108ms
  24.         Class.forName("oracle.jdbc.OracleDriver");
  25.         Connection connection = DriverManager.getConnection("jdbc:oracle:thin:127.0.0.1:1521:orcl", "xxx", "xxx");
  26.         connection.setAutoCommit(false);
  27.         PreparedStatement cmd = connection.prepareStatement("insert into t values(?)");
  28.         for (int i = 0; i < list.size(); i++) {
  29.             cmd.setString(1, list.get(i));
  30.             cmd.addBatch();
  31.             if (i % _1W == 0) {
  32.                 cmd.executeBatch();
  33.             }
  34.         }
  35.         cmd.executeBatch();
  36.         connection.commit();
  37.     }

  38.     public static void jdbcWrite() throws ClassNotFoundException, SQLException {
  39.         // 28189ms
  40.         Class.forName("oracle.jdbc.OracleDriver");
  41.         Connection connection = DriverManager.getConnection("jdbc:oracle:thin:127.0.0.1:1521:orcl", "xxx", "xxx");
  42.         connection.setAutoCommit(false);
  43.         PreparedStatement cmd = connection.prepareStatement("insert into t values(?)");
  44.         for (String s : list) {
  45.             cmd.setString(1, s);
  46.             cmd.execute();
  47.         }
  48.         connection.commit();
  49.     }

  50.     public static void jdbcRead() throws ClassNotFoundException, SQLException {
  51.         // 3120ms
  52.         Class.forName("oracle.jdbc.OracleDriver");
  53.         Connection connection = DriverManager.getConnection("jdbc:oracle:thin:127.0.0.1:1521:orcl", "xxx", "xxx");
  54.         connection.setAutoCommit(false);
  55.         PreparedStatement cmd = connection.prepareStatement("select * from t");
  56.         ResultSet rs = cmd.executeQuery();
  57.         int i = 0;
  58.         while (rs.next()) {
  59.             rs.getString(1);
  60.             i = i + 1;
  61.         }
  62.         System.out.println("count:" + i);
  63.     }

  64.     public static void fetchRead() throws ClassNotFoundException, SQLException {
  65.         //764ms
  66.         Class.forName("oracle.jdbc.OracleDriver");
  67.         Connection connection = DriverManager.getConnection("jdbc:oracle:thin:127.0.0.1:1521:orcl", "xxx", "xxx");
  68.         connection.setAutoCommit(false);
  69.         PreparedStatement cmd = connection.prepareStatement("select * from t");
  70.         cmd.setFetchSize(_1W);
  71.         ResultSet rs = cmd.executeQuery();
  72.         int i = 0;
  73.         while (rs.next()) {
  74.             rs.getString(1);
  75.             i = i + 1;
  76.         }
  77.         System.out.println("count:" + i);
  78.     }
  79. }
JDBC插入比較,相差25倍
    不帶Batch    28189ms
    Batch           1108ms 

JDBC讀取比較,相差4倍
    不帶Fetch    3120ms
    Fetch           764ms

如果把JDBC類比為JAVA IO的話,
不使用Fetch和Batch相當於直接使用FileInputStream和FileOutputStream
而設定了Fetch和Batch相當於使用BufferedInputStream和BufferedOutputStream

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29254281/viewspace-1063033/,如需轉載,請註明出處,否則將追究法律責任。

相關文章