39

私は今バッチを使用しています:

String query = "INSERT INTO table (id, name, value) VALUES (?, ?, ?)";
PreparedStatement ps = connection.prepareStatement(query);            
for (Record record : records) {
    ps.setInt(1, record.id);
    ps.setString(2, record.name);
    ps.setInt(3, record.value);
    ps.addBatch();
}
ps.executeBatch();

上記のコードが次のコードと同等かどうか疑問に思っています。そうでない場合、どちらが速いですか?

String query = "INSERT INTO table (id, name, value) VALUES ";
for (Record record : records) {
    query += "(" + record.id + ",'" + record.name + "'," + record.value + "),";
}
query = query.substring(1, query.length() - 1);
PreparedStatement ps = connection.prepareStatement(query);
ps.executeUpdate();
4

6 に答える 6

43

自動コミットをオフにします

executeBatchautocommitがfalseに設定されexecuteUpdateている限り、パフォーマンスが向上します。

connection.setAutoCommit(false);  
PreparedStatement ps = connection.prepareStatement(query);            
for (Record record : records) {
    // etc.
    ps.addBatch();
}
ps.executeBatch();
connection.commit(); 
于 2012-08-17T20:20:41.127 に答える
30

まず、クエリ文字列の連結では、PreparedStatement メソッドに固有の型変換が失われるだけでなく、データベースで実行される悪意のあるコードに対して脆弱になります。

第 2 に、PreparedStatement は以前はデータベース自体にキャッシュされていました。これにより、プレーンなステートメントよりもパフォーマンスが大幅に向上しています。

于 2012-08-17T20:17:06.243 に答える
1
public void insertBatch(final List<Record > records ) {

    String query = "INSERT INTO table (id, name, value) VALUES (?, ?, ?)";


    GenericDAO.getJdbcTemplate().batchUpdate(sql, new BatchPreparedStatementSetter() {


        @Override
        public void setValues(PreparedStatement ps, int i) throws SQLException {
              Record record = records .get(i);
              ps.setInt(1, record.id);
              ps.setString(2, record.name);
              ps.setInt(3, record.value);
        }

        @Override
        public int getBatchSize() {
            return records.size();
        }
    });
}
于 2014-04-30T11:53:59.763 に答える
1

In case that your records size is less than or equal to 1000 the following code is better than both of your codes:

StringBuilder query = new StringBuilder("INSERT INTO table (id, name, value) VALUES ");

if (records.size() <= 1000) {
    
    for (int i = 0; i < records.size(); i++)
        query.append("(?, ?, ?), ");

    query = new StringBuilder(query.substring(1, query.length() - 1));

    PreparedStatement ps = connection.prepareStatement(query.toString());

    for (int i = 0; i < records.size(); i++) {
        ps.setInt((i * 3) + 1, record.id);
        ps.setString((i * 3) + 2, record.name);
        ps.setInt((i * 3) + 3, record.value);
    }
    
    ps.executeUpdate();
    
}

In this way you are using PreparedStatement and create it dynamically depending the size of your record list using multiple values clause in one insert query

于 2021-01-06T06:35:54.183 に答える
-7

これでいいと思います

String query = "INSERT INTO table (id, name, value) VALUES ";
for (Record record : records)
{
query += "(" + record.id + ",'" + record.name + "'," + record.value + "),";
query = query.substring(1, query.length() - 1);
PreparedStatement ps = connection.prepareStatement(query);
ps.executeUpdate();
}

データベースに挿入するレコードごとにクエリを実行する必要があるためです。

于 2012-08-17T20:48:46.467 に答える