Android 中 SQLite 效能優化
阿新 • • 發佈:2019-02-18
建立索引
具體用法看上面的部落格。
優點:加快了查操作
缺點:降低了增刪改操作的速度,增加了空間消耗,建立索引過程耗時。
基於以上特點,具體情況判斷是否建立索引。
編譯SQL語句
SQLite想要執行操作,需要將程式中的sql語句編譯成對應的SQLiteStatement,比如select * from record這一句,被執行100次就需要編譯100次。對於批量處理插入或者更新的操作,我們可以使用顯式編譯來做到重用SQLiteStatement。
private void insertWithPreCompiledStatement(SQLiteDatabase db) {
String sql = "INSERT INTO " + TableDefine.TABLE_RECORD + "( " + TableDefine.COLUMN_INSERT_TIME + ") VALUES(?)";
SQLiteStatement statement = db.compileStatement(sql);
int count = 0;
while (count < 100) {
count++;
statement.clearBindings();
statement.bindLong(1, System.currentTimeMillis());
statement.executeInsert();
}
}
顯示執行事務(由於沒接觸過事務這部分所以不太懂,先記錄在此)
在Android中,無論是使用SQLiteDatabase的insert,delete等方法還是execSQL都開啟了事務,來確保每一次操作都具有原子性,使得結果要麼是操作之後的正確結果,要麼是操作之前的結果。
然而事務的實現是依賴於名為rollback journal檔案,藉助這個臨時檔案來完成原子操作和回滾功能。既然屬於檔案,就符合Unix的檔案範型(Open-Read/Write-Close),因而對於批量的修改操作會出現反覆開啟檔案讀寫再關閉的操作。然而好在,我們可以顯式使用事務,將批量的資料庫更新帶來的journal檔案開啟關閉降低到1次。、
private void insertWithTransaction(SQLiteDatabase db) {
int count = 0;
ContentValues values = new ContentValues();
try {
db.beginTransaction();
while (count++ < 100) {
values.put(TableDefine.COLUMN_INSERT_TIME, System.currentTimeMillis());
db.insert(TableDefine.TABLE_RECORD, null, values);
}
db.setTransactionSuccessful();
} catch (Exception e) {
e.printStackTrace();
} finally {
db.endTransaction();
}
}
查詢優化
查詢優化的幾點小細節:
1.按需獲取資料
2.提前獲取列索引
private void goodQueryWithLoop(SQLiteDatabase db) {
Cursor cursor = db.query(TableDefine.TABLE_RECORD, new String[]{TableDefine.COLUMN_INSERT_TIME}, null, null, null, null, null) ;
int insertTimeColumnIndex = cursor.getColumnIndex(TableDefine.COLUMN_INSERT_TIME);//先獲得索引
while (cursor.moveToNext()) {
long insertTime = cursor.getLong(insertTimeColumnIndex);
}
cursor.close();
}
3.ContentValues的容量調整
ContentValues的初始容量是8,如果當新增的資料超過8之前,則會進行雙倍擴容操作,因此建議對ContentValues填入的內容進行估量,設定合理的初始化容量,減少不必要的內部擴容操作。