2011年2月24日木曜日

Derbyに大量データをinsertしてみた

Apache Derbyに大量データをinsertしてみました。
Derbyには組み込みモードとサーバモードがありますが、組み込みモードでのみ確認しました。

Derbyを動かすまでの手順は以下の通り。基本的にはマニュアル通りです。
・Derby10.7.1.1をダウンロードする(現時点での最新)
・DERBY_HOMEを設定する
・$DERBY_HOME/binをPATHに追加
・$DERBY_HOME/lib/derby.jarをCLASSPATHに追加

・ijを実行し、testdbにConnectする
[user@user bin]$ ij
ij バージョン 10.7
ij> CONNECT 'jdbc:derby:testdb;create=true';

・hashテーブルの作成
ij> create table hash ( id integer PRIMARY KEY , value varchar(40));
0 行が挿入/更新/削除されました

下準備はこれで完了です。

毎回同様ですが、100万件のCSVネタを読み込みながらinsertを100万回行います。
以下、赤字が変更点です。
import java.sql.*;
import java.io.*;
import java.util.Date.*;

public class derbyins {
    public static void main (String args[]) {
        Connection db = null;
        PreparedStatement ps = null;
        String sql = "insert into hash values(?,?)";
        String url = "jdbc:derby:testdb";
        BufferedReader br = null;
        int i = 0;
        try {
            Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
            db = DriverManager.getConnection(url);
            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);
    }
 }

100万行insertするのに227sかかりました。SQLite3+JDBCよりもずいぶん遅く、PostgreSQL+JDBCよりも遅い結果となりました。

ApacheDerbyというものは今回初めて知ってさらっと使ってみましたが、非常に手軽に使えるのは間違いありません。Derbyのメリットをあげると以下でしょうか。
・JDBCの品質が高い(はず)
・組み込みモードとサーバモードの2種類で使える
・レプリケーションが標準で搭載されている

しかし、残念ながら日本ではDerbyを使っているという話は少なくともネット上には見受けられません。これは個人的には以下のような理由かなと思います。
・PublicDomainでは無い→Sqliteの方が使用のハードルが低い
・Sqliteの知名度に勝てない
・Javaでしか使えない
・さして高速でも無い

まあ、組み込みとサーバモード両方で使えたり、レプリケーション出来たりしても、私には使う場所が無いですね。全然Sqliteでいいです。