如何优化insert语句以达到最佳性能

时间:2015-08-12 10:43:07

标签: java sqlite jdbc

Iam使用JDBC",我写下了" insertRecord"它假设被多次调用并将记录插入数据库表中。当我为每500条记录运行代码时#34;批量大小为#34; 它需要20秒而且非常慢,因为该代码应该在不同的xml文件上运行30次以隔离它们并将一些数据插入到数据库表中。

是否有任何建议如何优化代码以达到最佳性能?

CreateTable方法

public void CreateTable(String tableName) throws SQLException, ClassNotFoundException {

    if (this.isTableExists(tableName)) {
        Log.i(TAG, "CreateTable", "table: ["+tableName+"] already exists.");

        this.connInsert  = this.getConnection();
        this.connInsert.setAutoCommit(true);
        this.psInsert = this.connInsert.prepareStatement("insert into "+this.TABLE_NAME+" ("+this.NODE_ID_COL+", "+this.LAT_COL+", "+this.LNG_COL+", "+this.XML_PATH_COL+") values (?, ?, ?, ?)");

    } else {
        Log.i(TAG, "CreateTable", "table: ["+tableName+"] does not exist, will be created");
        Connection conn = this.getConnection();
        Statement stmt = conn.createStatement();
        stmt.executeUpdate(this.sqlTable);

        stmt.close();
        conn.close();

        this.connInsert  = this.getConnection();
        this.connInsert.setAutoCommit(true);
        this.psInsert = this.connInsert.prepareStatement("insert into "+this.TABLE_NAME+" ("+this.NODE_ID_COL+", "+this.LAT_COL+", "+this.LNG_COL+", "+this.XML_PATH_COL+") values (?, ?, ?, ?)");

    }
}

insertRecord方法

public void insertRecord(Record rec) throws SQLException, ClassNotFoundException {

    if (this.isTableExists(this.TABLE_NAME)) {

        this.psInsert.setString(1, rec.getNodeID());
        this.psInsert.setString(2, rec.getLat());
        this.psInsert.setString(3, rec.getLng());
        this.psInsert.setString(4, rec.getPath());

        this.psInsert.addBatch();

        if (++this.batchCnt == SysConsts.BATCH_SIZE) {
            this.psInsert.executeBatch();
            this.batchCnt = 0;

            Log.d(TAG, "insertRecord", SysConsts.BATCH_SIZE+" records inserted.");
        }

    } else {
        Log.e(TAG, "insertRecord", "table: ["+this.TABLE_NAME+"] does not exist");
    }

}

fluch方法,用于刷新批次中的剩余记录

//this method should be called in the end of the code to flush the remaining records in the batch

public void flush() throws SQLException {
    this.psInsert.executeBatch();

    this.psInsert.close();
    this.connInsert.close();

    Log.d(TAG, "insertRecord", "the rest of the records flushed into data base table.");
}

2 个答案:

答案 0 :(得分:0)

以下是典型答案:

  • 使用相同的商店程序(或一些准备声明)
  • 在一次交易中包装所有插入(非常重要,因为它会减少io写入的数量)
  • 更改连接类型(例如sqlite中的journal)
  • 使用blob(非常罕见)

答案 1 :(得分:-1)

使用stored procedures。它们比正常的SQL执行速度快得多。

  

通常会缓存一个过程的查询计划,允许您重复使用它   一次又一次,无需重新准备。

     

由于存储过程是Parsed,一次编译,然后是   可执行文件缓存在数据库中。因此,如果相同的查询   重复多次,然后Database直接执行可执行文件   因此,时间保存在Parse,Compile等中。如果是查询,这是很好的   经常使用。如果不经常使用查询,则可能不是   好,因为存储缓存的可执行文件占用空间,为什么要加载   在数据库上不必要地。