簡體   English   中英

如何優化insert語句以獲得最佳性能

[英]how to optimize the insert statement to achive utmost performance

我使用JDBC" ,我寫了下面的“ insertRecord”方法,它想被調用很多次,並將記錄插入數據庫表中。當我為每500條記錄運行代碼時,“這是批大小”需要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.");
}

以下是典型的答案:

  • 使用相同的存儲過程(或與您相同的一些prepare語句)
  • 將所有插入內容包裝在一個事務中 (非常重要,因為這將減少io寫入的數量)
  • 更改連接類型(如sqlite中的日志)
  • 使用斑點(非常罕見)

使用存儲過程 它們比正常的SQL執行速度快得多。

一個過程的查詢計划通常是緩存的,使您可以一次又一次地重用它,而無需重新准備它。

由於存儲過程被解析,立即編譯,並且可執行文件被緩存在數據庫中。 因此,如果多次重復同一查詢,則數據庫直接執行可執行文件,因此將時間保存在Parse,Compile等中。如果頻繁使用查詢,則這樣做很好。 如果不經常使用查詢,則可能不是很好,因為存儲緩存的可執行文件會占用空間,因此為什么不必要將負載放在數據庫上。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM