Android SQLite效能分析

來源:互聯網
上載者:User

標籤:android   sqlite   webkit   

作為Android預置的資料庫模組,對SQLite的深入理解是非常有必要的,可以從中找到一些最佳化的方向。這裡對SQLite的效能和記憶體進行了一些測試分析,對比了不同操作的執行效能和記憶體佔用的情況,粗略地列在這裡算是作個小結。


1. 基本架構


先瞭解一下SQLite主要架構 (詳見《The Definitive Guide to SQLite》), 需要關注的是Compiler和Backend兩個模組。正因為有一個虛擬機器的存在,所以才有了Compiled Statement的價值,因為它可以減少前置的編譯時間,直接到VDBE上執行。而Backend端的Pager,則是重要資料管理者,真正決定者資料操作的效能,以及記憶體佔用。


這裡不再贅述,詳細的內容還是閱讀有關SQLite介紹的資料。



2. 效能


這次測試基於Sumsung i9103和Google Nexus S1進行。使用Python指令碼及adb指令通過Intent操作Android應用進行資料庫操作。


i. SELECT操作

首先觀察到SELECT在不同記錄數下的峰值分布,可見整體上有上升的趨勢。正如SQLite官方說的它並不適合儲存大量資料,一定要控制其中的記錄數量。

另外SELECT操作效能也取決於查詢的欄位個數,而@行雲進一步確認和返回欄位的內容大小有關,也就是欄位的內容和多少也需要權衡。



ii. 關於事務

事務是提高SQLite操作效能的一個重要技術,特別是SQLite實現了WAL,使得事務與SELECT不會互斥,大大提高了應用的效能。參見附2。


下面是未使用事務時,三類操作的平均值:


使用了事務後,各個操作的效能大幅下降。


但是問題是事務提交的時間會變長,這個時間一是需要形成新的峰值,另外也要平分到各個操作來看:

     

所以不能貪多,事務還是要及時提交。另外注意, 雖然Compiled Statement有利於效能表現,但還不如使用事務的效果來得直接。


iii. 不同機型的操作效能

先看SELECT操作的平均值在兩種機型上的表現, 可以看到i9103上的波動性比較大,而Nexsus S1則一直保持穩定:

散佈圖,可以觀察到時間分布情況:




再看另外三個操作的表現(上下兩部分false和true分別表示為未使用事務和使用事務的情況):



運用WAL可以大幅提升效能,不過它也有一個副作用。它會導致資料查詢需要進行兩次,可以理解為一次在db檔案,一次在wal檔案。具體原因參見<<The Definitive Guide to SQLite>>最後一章。WAL是滿1000Pages時才會合并到主要資料庫裡,這個時機稱為checking point, 可以進行配置。按預設的Page Size:1024計算,也就是當WAL檔案接近1M時,進行檢查。如果沒有活動的事務使用這些pages,就會提交。而WAL的大小,對SELECT的影響表現不同。


下面是WAL對查詢效能峰值影響的測試資料(i9103上測試),圖中的true,false表示是否有WAL檔案存在。


 *整體的平均值相差在1ms,但峰值的才是真正值得注意的。


為了避免WAL過大,可以選擇調用SQLiteDatabase::disableWriteAheadLogging()強制合并到主要資料庫檔案,這個調用會非同步在SQLite內部執行,不會明顯阻塞使用者的線程。


*另外,SQLiteDatabase::query()只是對SQLiteDatabase::rawQuery()的封裝,多了一個字串組裝的過程,反而不如直接使用SQLiteDatabase::rawQuery()。



3. 記憶體 


SQLite以Page為單位儲存資料,預設一個Page有1024位元組,然後通過B- Tree組織起來(Table使用B+ Tree組織):



Lookaside則是SQLite應用的記憶體管理的技術,最佳化了記憶體的使用效率,主要思想是先分配一整塊記憶體, 分成若干個slots,然後SQLite再按需使用。這個許多小記憶體 Clerk的思想是一樣的。詳見附1。


再解釋一下Page Cache Overflow, 主要是在一個Page中的記錄的資料無法剛好放在一個Page內,還要使用額外的另一個Page空間, 這就是Overflow Page。

     


Android還有個萬能dumpsys, 使用dumpsys meminfo可以查看到一個進程的SQLite使用的記憶體資訊。如:

SQL

                heap:      265          MEMORY_USED:      265

  PAGECACHE_OVERFLOW:       73          MALLOC_SIZE:       46

 

 DATABASES

      pgsz     dbsz   Lookaside(b)          cache  Dbname

         4       60             17      199/114/1  webviewCache.db

                                          1/541/1  (pooled # 1) webviewCache.db


   . cache的三個值分別是:

        Page Cache的叫用次數、未叫用次數,以及Page Cache個數。可以在Android源碼中的SQLiteDebug.java以及ActivityThread.java找到細節的內容。

   . page size, db size的單位是KBytes, Lookaside(b)是指使用多少個Lookaside的slots。

   . 對於Heap和Overflow Pages,SQLiteDatabase的記憶體回收可能沒有那麼及時,可以調用SQLiteDatabase::releaseMemory()進行主動釋放。


*使用SQLite的PRAGMA可以直接擷取一些通過SQLiteDatabase擷取不到資訊,當然如果SQLite不支援,也會拋異常出來,詳見附4。


轉載請註明出處: http://blog.csdn.net/horkychen  SQLite是一個非常精緻的系統,很值得研究學習。


參考

  1. SQLite Dynamic Memory Allocation

  2. Write-Ahead Logging 或 SQLite的WAL機制

  3. The Definitive Guide to SQLite(兩處關於架構和Overflow page的來於此書.)

  4. PRAGMA Statement

  5. 官方文檔

  6. NEC關於Android系統上儲存空間操作效能的研究報告




Android SQLite效能分析

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.