Android 往Sqlitedatabase中插入大量資料效率問題,40倍效率加速你的操作
阿新 • • 發佈:2019-02-01
情景:我現在要往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();
}