1. 程式人生 > >Android 往Sqlitedatabase中插入大量資料效率問題,40倍效率加速你的操作

Android 往Sqlitedatabase中插入大量資料效率問題,40倍效率加速你的操作

情景:我現在要往sqlite database中的表中(R_USER_QUESTION_DO_HISTORY)插入十萬條資料

1.我的程式碼:

  public void setUpDataBaseForUser(String userID) {
        String[] column = {
                Config.COLUMN_USERID,
        };
        String selection = "UserID = '" + userID + "'";
        Cursor cursor = database.query(Config.TABLE_R_USER_QUESTION_DO_HISTORY, column, selection, null
, null, null, null); if (cursor.getCount() == 0) { //初始化表: R_User_Question_Do_History int rowNum = getTotalRowInTable(Config.TABLE_R_USER_QUESTION_DO_HISTORY); try { ContentValues values = new ContentValues(); for (int i = 0; i < 100000
; i++) { values.put(Config.COLUMN_USERID, userID); rowNum = ++rowNum; values.put(Config.COLUMN_QUESTIONNUM, rowNum + ""); values.put(Config.COLUMN_ISCOLLECTED, 0); values.put(Config.COLUMN_WRONGTIMES, 0
); values.put(Config.COLUMN_RIGHTTIMES, 0); database.insert(Config.TABLE_R_USER_QUESTION_DO_HISTORY, null, values); } } catch (Exception e) { throw e; } finally { cursor.close(); } } }

在activity中呼叫這個方法:

 DBUtil dbUtil = new DBUtilConcreate();
        dbUtil.initDataBase();
        System.out.println("準備插入資料,當前時間:" + (new Date()));
        dbUtil.setUpDataBaseForUser("A101");
        System.out.println("資料插入結束,當前時間:"+(new Date()));

程式碼的確能完成100000條資料的插入,但是當把app執行起來的時候,卻發現,這個功能卻花費了5分鐘都沒有完成,你可以看到下
插入資料之前的時間是:11:32:01

資料插入成功的時候卻是:11:37:13

試想一下,如果一個app為了完成這個功能花了5分鐘都沒有完成話,那麼還會有誰會想用這個app?

這裡寫圖片描述
2.接下來就是提高效率的時候了:

對原來的程式碼稍作修改:

public void setUpDataBaseForUser(String userID) {
        String[] column = {
                Config.COLUMN_USERID,
        };
        String selection = "UserID = '" + userID + "'";
        Cursor cursor = database.query(Config.TABLE_R_USER_QUESTION_DO_HISTORY, column, selection, null, null, null, null);
        if (cursor.getCount() == 0) {
            //初始化表: R_User_Question_Do_History
            int rowNum = getTotalRowInTable(Config.TABLE_R_USER_QUESTION_DO_HISTORY);
            //加上的程式碼
            database.beginTransaction();
            try {
                ContentValues values = new ContentValues();
                for (int i = 0; i < 100000; i++) {
                    values.put(Config.COLUMN_USERID, userID);
                    rowNum = ++rowNum;
                    values.put(Config.COLUMN_QUESTIONNUM, rowNum + "");
                    values.put(Config.COLUMN_ISCOLLECTED, 0);
                    values.put(Config.COLUMN_WRONGTIMES, 0);
                    values.put(Config.COLUMN_RIGHTTIMES, 0);
                    database.insert(Config.TABLE_R_USER_QUESTION_DO_HISTORY, null, values);
                }
                //加上的程式碼
                database.setTransactionSuccessful();
            } catch (Exception e) {
                throw e;
            } finally {
                cursor.close();
                //加上的程式碼
                database.endTransaction();
            }
        }
    }

現在再執行一次,
這裡寫圖片描述
你可以清清楚楚地看到,

插入資料之前的時間是:11:39:57
資料插入結束時間是:11:40:05

是的,加了三行程式碼之後,只花了8秒的時間,只用了原來的1/40左右。

這是為什麼呢?
因為我們每一次insert操作,都涉及一次磁碟操作,10000次條資料就是10000次磁碟操作,我們的時間都浪費在了磁碟操作上。
我們把10000次地insert操作作為一個事物,來操作,減少磁碟操作次數,所用時間自然而然地就快了不少,那可是將近40倍地效率啊。

使用SQLiteDatabase的beginTransaction()方法可以開啟一個事務,程式執行到endTransaction() 方法時會檢查事務的標誌是否為成功,如果程式執行到endTransaction()之前呼叫了setTransactionSuccessful() 方法設定事務的標誌為成功,則所有從beginTransaction()開始的操作都會被提交,如果沒有呼叫setTransactionSuccessful() 方法則回滾事務。

android中的事物使用方法:

              database.beginTransaction();
            try {
                //這裡寫你的程式碼

                database.setTransactionSuccessful();
            } catch (Exception e) {
                throw e;
            } finally {

                database.endTransaction();
            }