HSQLDB 2.0 のインメモリDBの性能を比べてみた

少し前の話しになりますが、HyperSQL が5年の歳月を経て2.0にメジャーバージョンアップされました。新機能の詳細は http://hsqldb.org/web/features200.html となりますが、SQL標準への準拠、マルチコア対応、スケーラビリティ向上、クエリ最適化、ストアドプロシージャの対応等山盛りです。

比較

hsqldb-2.0.1-rc2、hsqldb-2.0.0、hsqldb_1_8_1_3、そして対抗馬の h2-1.3.146 をインメモリDBとして使用して性能を比較してみよ。といっても単純なINSERT、UPDATE、SELECT の実行時間見るだけですがー

ソースは

単純な例で。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class Main {
    public static void main(String[] args) throws Exception {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        try {
            conn = getConnection();
            stmt = conn.createStatement();
            conn.setAutoCommit(false);
            stmt.executeUpdate("CREATE TABLE key_value (key Integer, value VARCHAR(128), PRIMARY KEY (key))");

            // insert
            long start = System.currentTimeMillis();
            for(int i=0;i<100000;i++) {
                stmt.executeUpdate("INSERT INTO key_value VALUES("+i+", 'foobar')");
            }
            conn.commit();
            System.out.println("INSERT : " + (System.currentTimeMillis()-start));

            // update
            start = System.currentTimeMillis();
            stmt.executeUpdate("UPDATE key_value SET value = 'bar'");
            conn.commit();
            System.out.println("UPDATE : " + (System.currentTimeMillis()-start));
            
            // select
            conn.setAutoCommit(true);
            start = System.currentTimeMillis();
            rs = stmt.executeQuery("SELECT key, value FROM key_value");
            while (rs.next()) {
                rs.getString(2);
            }
            System.out.println("SELECT : " + (System.currentTimeMillis()-start));

        } catch (SQLException e) {
            if (conn != null) {
                conn.rollback();
                conn.setAutoCommit(true);
            }
            handleSqlException(e);
        } finally {
            try {
                rs.close();
                stmt.close();
                conn.close();
            } catch (Exception e) {
            }
        }
    }

    public static Connection getConnection() throws Exception {
        Class.forName("org.hsqldb.jdbc.JDBCDriver");
        return DriverManager.getConnection("jdbc:hsqldb:mem:mymemdb", "SA", "");
    }

    private static void handleSqlException(SQLException e) {
        System.out.println("--- SQLException ---");
        while (e != null) {
            System.out.println("Message   : " + e.getMessage());
            System.out.println("SQLState  : " + e.getSQLState());
            System.out.println("ErrorCode : " + e.getErrorCode());
            System.out.println("---");
            e = e.getNextException();
        }
    }
}


HSQLDB 1.8.1.3 の場合は

public static Connection getConnection() throws Exception {
    Class.forName("org.hsqldb.jdbcDriver");
    return DriverManager.getConnection("jdbc:hsqldb:mem:mymemdb", "SA", "");
}


H2 1.3.146 の場合は

public static Connection getConnection() throws Exception {
    Class.forName("org.h2.Driver");
    return DriverManager.getConnection("jdbc:h2:mem:mymemdb", "SA", "");
}

結果

各5回の平均をグラフにすると、

  • INSERT は HSQLDB 1.8.1.3 が最速、HSQLDB 2.0 系は遅い
  • UPDATE は H2 1.3.146 が一番遅い
  • SELECT は HSQLDB 1.8.1.3 が一番遅く、H2が早い

HSQLDB 2.0 は機能拡張の影響か速度的には遅くなっています。古い HSQLDB 1.8 は機能がシンプルなためか良いパフォーマンスとなっています。
ここまでやっといて何ですが、同時トランザクション数等が増えた場合にはHSQLDB 2.0 のパフォーマンスがよくなってくるのでしょう。単純な例だけでは比較できません。。

結果内訳

hsqldb-2.0.1-rc2

操作 1回目 2回目 3回目 4回目 5回目 平均
INSERT 4711 4883 4836 4509 4323 4652.4
UPDATE 983 1201 1186 998 953 1064.2
SELECT 156 234 218 140 219 193.4


hsqldb-2.0.0

操作 1回目 2回目 3回目 4回目 5回目 平均
INSERT 4160 4597 3534 3831 4191 4062.6
UPDATE 1219 969 1204 938 1204 1106.8
SELECT 235 203 234 250 234 231.2


hsqldb_1_8_1_3

操作 1回目 2回目 3回目 4回目 5回目 平均
INSERT 2408 2876 2485 2376 2470 2523
UPDATE 1031 1063 813 1047 1032 997.2
SELECT 250 266 188 250 250 240.8


h2-1.3.146

操作 1回目 2回目 3回目 4回目 5回目 平均
INSERT 3080 2830 3158 3080 2486 2926.8
UPDATE 954 1469 1454 1313 1360 1310
SELECT 156 188 188 125 172 165.8