少し前の話しになりますが、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", ""); }
結果
- 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 |