2011年2月8日火曜日

JavaでPostgreSQLに大量データをinsertしてみた

JAVAからPostgreSQLに例によって大量データをINSERTしてみました。
環境は以下です。
・Fedora13+PostgreSQL9.0 + JDBCも9.0(Type4)+JAVA6
以下のようなコードを作成しました。見苦しいところはお許しを。。

import java.sql.*;
import java.io.*;
import java.util.Date.*;
public class postgresqlins {
public static void main (String args[]) {
            Connection db = null;
            PreparedStatement ps = null; 
            String sql = "insert into hash values(?,?)";
            String url = "jdbc:postgresql:testdb";
            String usr = "postgres";
            String pwd = "postgres";
            BufferedReader br = null;
            int i = 0;
            try {
               Class.forName("org.postgresql.Driver");
               db = DriverManager.getConnection(url, usr, pwd);
               db.setAutoCommit(false);
               ps = db.prepareStatement(sql);
            ) catch (Exception ex) {
               ex.printStackTrace();
            }
            java.util.Date d1 = new java.util.Date();
            System.out.println(d1);
            try{
                 br = new BufferedReader(new(InputStreamReader(new(FileInputStream("neta.csv")));
                String line;
                while( (line = br.readLine()) != null ){
                   i++;
                   String[] col = line.split(",");
                   int id = new Integer(col[0]);
                   String value = col[1];
                   ps.setInt(1,id);
                   ps.setString(2,value);
                   ps.executeUpdate();
                   if( i % 10000 == 0) { 
                        System.out.println(i);
                        db.commit();
                   }
                }
                db.commit();
                ps.close();
                db.close();
                br.close();
           } catch (Exception ex) {
                ex.printStackTrace();
           }
           java.util.Date d2 = new java.util.Date();
           System.out.println(d2);
      }
}

以前と同様にneta.csvという100万件のデータを読み込んで、PostgreSQLにINSERTしています。INSERTにかかった時間は130sでした。
以下は感想。
・JDBCはやっぱり安定している。(Pythonと違って戸惑う事が無し!)
・Pythonのドライバと比較すると、約10倍速い。
・この差は果たして、言語的なものなのか、ドライバの優劣なのか、アプリがおかしいのか?は不明でした。
・ps = db.prepareStatement(sql) のコードをwhileループの中に書くと倍以上遅くなる。構文解析(PARSE)処理が多発するからでしょう。
・Commitタイミングを10万件にしてやってみたが、大差は無かった。