プログラム悪戦苦闘日記

はてなダイアリーからの移行(遺物)

PreparedStatementは無印Statementより早いのか -part3-

 Webアプリケーションで使う、という条件に近づけるためにConnectionをプールして測定をしてみた。入力データなどの条件は前回と同じである。

import java.util.*;
import java.sql.*;
import javax.naming.*;
import javax.sql.*;

public class Main {
    static final String url = "jdbc:odbc:Sample";
    static final Random random = new Random();
    static final int MAX = 1000;
    
    public static void main(String[] args) throws Exception {
        Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
        Connection con =  DriverManager.getConnection(url, "", "");
        
        final long start = System.nanoTime();
        
        if( "type1".equals(args[0]) ) {
            for(int i=1; i<=MAX; ++i) type1(con);
        }else {
            for(int i=1; i<=MAX; ++i) type2(con);
        }
        
        final long end = System.nanoTime();
        
        System.out.println("経過時間:" + ((end - start) / (1000000.0*MAX)) + "msec / 回");
        
        con.close();
    }
    
    static void type1(Connection con) throws Exception {
        Statement st = con.createStatement();
        ResultSet rs = st.executeQuery("select * from Sample2 where STR1 = '" + random.nextInt(1000) + "';");
        rs.next();
        rs.close();
        st.close();
    }
    
    static void type2(Connection con) throws Exception {
        PreparedStatement st = con.prepareStatement("select * from Sample2 where STR1 = ?;");
        st.setInt(1, random.nextInt(1000));
        ResultSet rs = st.executeQuery();
        rs.next();
        rs.close();
        st.close();
    }
}

 測定結果は、

無印Statement:    経過時間:2.653516857msec / 回
PreparedStatment: 経過時間:6.089681231msec / 回

標準偏差を求めていないので、これに有意な差があるかは判断できないが、少なくても前回の結果と合わせると、PreparedStatmentもプールしないと無印Statementより速くならない、といっていいだろう。PreparedStatementの動作を理解していれば、当たり前の結果なのだろうが、どのサイトをみても、無条件でPreparedStatementを使うと書かれているので、調べてみました。