Android數據庫優化

一、索引android

簡單的說,索引就像書本的目錄,目錄能夠快速找到所在頁數,數據庫中索引能夠幫助快速找到數據,而不用全表掃描,合適的索引能夠大大提升數據庫查詢的效率。
(1). 優勢
大大加快了數據庫檢索的速度,包括對單表查詢、連表查詢、分組查詢、排序查詢。常常是一到兩個數量級的性能提高,且隨着數據數量級增加。sql

 

(2). 缺點
索引的建立和維護存在消耗,索引會佔用物理空間,且隨着數據量的增長而增長。
在對數據庫進行增刪改時須要維護索引,因此會對增刪改的性能存在影響。

數據庫

 

二、使用事務
使用事務的兩大好處是原子提交和更優性能。
(1) 原子提交
原則提交意味着同一事務內的全部修改要麼都完成要麼都不作,若是某個修改失敗,會自動回滾使得全部修改不生效。多線程

 

(2) 更優性能
Sqlite默認會爲每一個插入、更新操做建立一個事務,而且在每次插入、更新後當即提交。併發

這樣若是連續插入100次數據實際是建立事務->執行語句->提交這個過程被重複執行了100次。若是咱們顯示的建立事務->執行100條語句->提交會使得這個建立事務和提交這個過程只作一次,經過這種一次性事務可使得性能大幅提高。尤爲當數據庫位於sd卡時,時間上能節省兩個數量級左右。異步

Sqlte顯示使用事務,示例代碼以下:ide

public void insertWithOneTransaction() {
    SQLiteDatabase db = sqliteOpenHelper.getWritableDatabase();
    // Begins a transaction
    db.beginTransaction();
    try {
        // your sqls
        for (int i = 0; i < 100; i++) {
            db.insert(yourTableName, null, value);
        }
 
        // marks the current transaction as successful
        db.setTransactionSuccessful();
    } catch (Exception e) {
        // process it
        e.printStackTrace();
    } finally {
        // end a transaction
        db.endTransaction();
    }
}
其中sqliteOpenHelper.getWritableDatabase()表示獲得寫表權限。性能

 

三、其餘針對Sqlite的優化
(1) 語句的拼接使用StringBuilder代替String
這個就很少說了,簡單的string相加會致使建立多個臨時對象消耗性能。StringBuilder的空間預分配性能好得多。若是你對字符串的長度有大體瞭解,如100字符左右,能夠直接new StringBuilder(128)指定初始大小,減小空間不夠時的再次分配。優化

 

(2) 查詢時返回更少的結果集及更少的字段。
查詢時只取須要的字段和結果集,更多的結果集會消耗更多的時間及內存,更多的字段會致使更多的內存消耗。ui

 

(3)cursor使用後要及時關閉:即在查詢完結果後,調用cursor.close()將資源關閉。

 

(4) 少用cursor.getColumnIndex

根據性能調優過程當中的觀察cursor.getColumnIndex的時間消耗跟cursor.getInt相差無幾。能夠在建表的時候用static變量記住某列的index,直接調用相應index而不是每次查詢。

 

public static final String      HTTP_RESPONSE_TABLE_ID                  =android.provider.BaseColumns._ID;


public static final String      HTTP_RESPONSE_TABLE_RESPONSE            ="response";


publicList<Object>getData(){


……


cursor.getString(cursor.getColumnIndex(HTTP_RESPONSE_TABLE_RESPONSE));


……


}

優化爲

 

public static final String       HTTP_RESPONSE_TABLE_ID                  = android.provider.BaseColumns._ID;
public static final String       HTTP_RESPONSE_TABLE_RESPONSE            = "response";
public static final int          HTTP_RESPONSE_TABLE_ID_INDEX            = 0;
public static final int          HTTP_RESPONSE_TABLE_URL_INDEX           = 1;
public List<Object> getData() {
……
cursor.getString(HTTP_RESPONSE_TABLE_RESPONSE_INDEX);
……
}

 

四、異步線程
Android中數據很少時表查詢可能耗時很少,不會致使anr,不過大於100ms時一樣會讓用戶感受到延時和卡頓,能夠放在線程中運行,但sqlite在併發方面存在侷限,多線程控制較麻煩,這時候可以使用單線程池,在任務中執行db操做,經過handler返回結果和ui線程交互,既不會影響UI線程,同時也能防止併發帶來的異常。

可以使用Android提供的AsyncQueryHandler(感謝@內網沒法登錄帳號 反饋)或相似以下代碼完成:

 

ExecutorService singleThreadExecutor=Executors.newSingleThreadExecutor();


singleThreadExecutor.execute(newRunnable(){


 


@Override


publicvoidrun(){


//
db operetions, u can use handler to send message after


db.insert(yourTableName,null,value);


handler.sendEmptyMessage(xx);


}

});

相關文章
相關標籤/搜索