朱 威
(湖南強(qiáng)智科技發(fā)展有限公司,湖南長(zhǎng)沙410205)
Android開發(fā)環(huán)境中的SQLite性能優(yōu)化
朱威
(湖南強(qiáng)智科技發(fā)展有限公司,湖南長(zhǎng)沙410205)
以Android開發(fā)環(huán)境中SQLite數(shù)據(jù)庫(kù)的性能和資源占用為研究對(duì)象,剖析了SQLite的體系結(jié)構(gòu),提出且深入分析了SQLite優(yōu)化方法,并向數(shù)據(jù)庫(kù)中插入1000條數(shù)據(jù)來(lái)加以驗(yàn)證。驗(yàn)證結(jié)果表明,通過(guò)一次性事務(wù)可以使得性能大幅提升。
Android;SQLite;性能優(yōu)化;驗(yàn)證測(cè)試
Google為Andriod的數(shù)據(jù)處理提供了SQLite,SQLite是一款非常流行的嵌入式數(shù)據(jù)庫(kù),它支持SQL查詢,可移植性好,很容易使用。高效而且可靠的Android在運(yùn)行時(shí)集成了SQLite,所以每個(gè)Android應(yīng)用程序都可以使用SQLite數(shù)據(jù)庫(kù)。SQLite有一個(gè)簡(jiǎn)潔的SQL接口,且以低內(nèi)存占用著稱。本文主要討論在Android開發(fā)環(huán)境中如何優(yōu)化SQLite的性能和資源占用。
SQLite是一個(gè)開源的嵌入式數(shù)據(jù)庫(kù),它支持SQL語(yǔ)言,由以下幾個(gè)組件組成:SQL編譯器、內(nèi)核、后端以及附件。SQLite架構(gòu)(architecture)如圖1所示。
1)編譯器(Compiler)
詞法分析器(Tokenizer)負(fù)責(zé)把原有字符串分割成一個(gè)個(gè)標(biāo)識(shí)符,語(yǔ)法分析器(Parser)負(fù)責(zé)在指定的上下文中賦予標(biāo)識(shí)符具體的含義。在編譯器中,詞法分析器和語(yǔ)法分析器檢查SQL語(yǔ)法,然后把它轉(zhuǎn)化為B-樹(B-Tree)這種數(shù)據(jù)結(jié)構(gòu),語(yǔ)法分析器在把標(biāo)識(shí)符組裝成完整的SQL語(yǔ)句后,調(diào)用代碼生成器(Code Generator)產(chǎn)生虛擬機(jī)代碼,最后由虛擬機(jī)(Virtual Machine)執(zhí)行SQL語(yǔ)句請(qǐng)求的工作。
圖1 SQLite架構(gòu)
2)接口(Interface)
接口由源文件main.c、vdbeapi.c和legacy.c組成,函數(shù)會(huì)去訪問(wèn)有文件作用域的數(shù)據(jù)結(jié)構(gòu),所以這些函數(shù)對(duì)分散在其他文件中的程序形成依賴。SQLite庫(kù)以sqlite3為前綴命名外部符號(hào),這些符號(hào)用來(lái)形成SQLite的API。
3)虛擬機(jī)(Virtual Machine)
架構(gòu)中最核心的部分是虛擬機(jī),虛擬機(jī)實(shí)現(xiàn)一個(gè)專為操作數(shù)據(jù)庫(kù)文件而設(shè)計(jì)的抽象計(jì)算引擎,所以也稱虛擬數(shù)據(jù)庫(kù)引擎(VDBE)。代碼生成器(Code Generator)生成代碼并由虛擬機(jī)(Virtual Machine)來(lái)執(zhí)行。虛擬機(jī)被包含在一個(gè)單獨(dú)的文件vdbe.c中,它有自己的頭文件,它們主要集中在數(shù)據(jù)庫(kù)操作。
4)后端(Back-End)
后端由B-tree、page cache(pager)和系統(tǒng)調(diào)用構(gòu)成。B-樹(B-tree)、頁(yè)緩存(pager)共同管理數(shù)據(jù)。B-樹的實(shí)現(xiàn)位于源文件btree.c中,主要功能就是索引,便于快速找到頁(yè)面之間需要的數(shù)據(jù)。而pager負(fù)責(zé)讀、寫和緩存這些數(shù)據(jù),并且管理數(shù)據(jù)文件的鎖定。
通過(guò)利用虛擬機(jī)和虛擬數(shù)據(jù)庫(kù)引擎(VDBE),SQLite實(shí)現(xiàn)了多數(shù)的SQL-92標(biāo)準(zhǔn),將SQL語(yǔ)句編譯成在SQLite虛擬機(jī)(Virtual Machine)中執(zhí)行的程序集。
在Android開發(fā)環(huán)境中如何優(yōu)化SQLite的性能和資源占用?主要通過(guò)以下兩種方法。
2.1使用事務(wù)(Transaction)
一般而言,SQL語(yǔ)句存在全新的事務(wù)內(nèi)。例如,執(zhí)行一個(gè)如INSERT這樣基本的數(shù)據(jù)庫(kù)操作,就會(huì)放到一個(gè)新創(chuàng)建的事務(wù)中執(zhí)行。一次只需要操作一次數(shù)據(jù)庫(kù)操作時(shí),讓SQLite自己來(lái)進(jìn)行事務(wù)管理當(dāng)然是明智的。但如果一次有大量的操作要做時(shí),比如循環(huán)調(diào)用INSERT添加時(shí),這樣就顯得開銷過(guò)大了,因?yàn)槊恳还P操作都要重新打開、寫入,最后再關(guān)閉journal文件,這個(gè)文件是臨時(shí)用來(lái)保存數(shù)據(jù)操作的中間結(jié)果。
如果明確地在一系列SQL語(yǔ)句前后以BEGIN TRANSACTION及END TRANSACTION這樣顯示地使用事務(wù)就可以避免上面的情況。程序如下所示:
使用事務(wù)有兩大好處:
1)原子提交
原則提交意味著同一事務(wù)內(nèi)的所有修改要么都完成要么都不做,如果某個(gè)修改失敗,會(huì)自動(dòng)回滾使得所有修改不生效。
2)更優(yōu)性能
Sqlite默認(rèn)會(huì)為每個(gè)插入、更新操作創(chuàng)建一個(gè)事務(wù),并且在每次插入、更新后立即提交。如果我們顯示的創(chuàng)建事務(wù)->執(zhí)行LENGTH條語(yǔ)句->提交會(huì)使得這個(gè)創(chuàng)建事務(wù)和提交這個(gè)過(guò)程只做一次,通過(guò)這種一次性事務(wù)可以使得性能大幅提升。尤其當(dāng)數(shù)據(jù)庫(kù)位于sd卡時(shí),時(shí)間上能節(jié)省兩個(gè)數(shù)量級(jí)左右。
2.2使用索引(index)
如果沒有在數(shù)據(jù)庫(kù)使用索引,當(dāng)你在一個(gè)沒有排序的數(shù)據(jù)表中使用映射查詢(projection query)搜索時(shí),無(wú)可避免的要執(zhí)行一個(gè)全序列查找。這種情況通常并不是什么問(wèn)題,每種數(shù)據(jù)庫(kù),包括SQLite都會(huì)為數(shù)據(jù)集執(zhí)行索引來(lái)降低查找時(shí)間。
索引維護(hù)著一個(gè)表中某一列或某幾列的順序,這樣就可以快速定位到一組值,而不用掃遍全表。所有的索引信息會(huì)被保存在一個(gè)獨(dú)立的索引表中,所以會(huì)產(chǎn)生額外的空間占用,不過(guò)絕對(duì)物超所值,特別是當(dāng)你會(huì)在數(shù)據(jù)庫(kù)中進(jìn)行大量的讀及搜索操作時(shí)。
SQLite會(huì)自動(dòng)為每一個(gè)UNIQUE欄位創(chuàng)建索引,包括主鍵(Primary Key)欄位,另外也可以通過(guò)CREATE INDEX進(jìn)行顯示地創(chuàng)建。
使用索引有四種方式:直接創(chuàng)建索引和間接創(chuàng)建索引、普通索引和唯一性索引、單個(gè)索引和復(fù)合索引、聚簇索引和非聚簇索引。
測(cè)試用例:向SQLite數(shù)據(jù)庫(kù)中插入1000條數(shù)據(jù)。
測(cè)試分析:如果僅僅是執(zhí)行
sqlite3_exec(db,"insert into name values'lxkxf','24';",0,0,&zErrMsg);
會(huì)重復(fù)1000次打開關(guān)閉數(shù)據(jù)庫(kù),因此應(yīng)該使用“事務(wù)”。
測(cè)試方法:添加SQLite語(yǔ)句
rc=sqlite3_exec(db,"BEGIN;",0,0,&zErrMsg);
執(zhí)行SQL語(yǔ)句
rc=sqlite3_exec(db,"COMMIT;",0,0,&zErrMsg);
只有這樣,SQL等到COMMIT時(shí)會(huì)一次性地寫入數(shù)據(jù)庫(kù),只需打開關(guān)閉1次數(shù)據(jù)庫(kù)文件,大幅提高效率。
測(cè)試數(shù)據(jù):、
1000 INSERTs
CREATE TABLE t1(a INTEGER,b INTEGER,c VARCHAR(100));
INSERT INTO t1 VALUES(1,13153,'thirteen thousand one hundred fifty three');
INSERT INTO t1 VALUES(2,75560,'seventy five thousand five hundred sixty');
...995 lines omitted
INSERT INTO t1 VALUES(998,66289,'sixty six thousand two hundred eighty nine');
INSERT INTO t1 VALUES(999,24322,'twenty four thousand three hundred twenty two');
INSERT INTO t1 VALUES(1000,94142,'ninety four thousand one hundred forty two');
SQLite 2.7.6:
13.061
SQLite 2.7.6(nosync):
SQLite數(shù)據(jù)庫(kù)的操作都是對(duì)文件的操作,頻繁訪問(wèn)文件相當(dāng)耗時(shí),大大降低了存取數(shù)據(jù)速度。本文提出的使用索引與事物兩種方法,較好地解決了以上問(wèn)題。
[1]Li W,Lu D.The Application of LBS Based on Android[M]. Network Computing and Information Security.Springer Berlin Heidelberg.2012.775-782.
[2]Vanjire S,Kanchan U,Shitole G,etal.Location Based Services on Smart Phone through the Android Application[J].provider,2014,3(1):23-27.
[3]楊明羽.Android語(yǔ)法范例參考大全[M].北京:電子工業(yè)出版社,2012.
[4]Kushwaha A,Kushwaha V.Location Based Services using Android Mobile Operating System[J].International Journal of Advances in Engineering&Technology,2011,1(1):14-20.
SQLite performance optimization in Android development environment
ZHU Wei
(Hunan Qiangzhi Science and Technology Development Corporation,Ltd.,Changsha,Hunan,China 410205)
Taking the characters and resource consumption of SQLite database in Android environment as the object of research,this paper analyzes the SQLite system structure and the SQLite optimization and checks with a thousand inserted data in the database.The result shows that the performance can be greatly improved by one try.
Android;SQLite;performance optimization;test and check
10.3969/j.issn.2095-7661.2015.01.010】
TP311.13
A
2095-7661(2015)01-0041-03
2015-01-06
朱威(1982-),男,湖南雙峰人,湖南強(qiáng)智科技發(fā)展有限公司技術(shù)部經(jīng)理,學(xué)士,研究方向:計(jì)算機(jī)應(yīng)用技術(shù)。