iOS 平台 SQLite 性能優化

開始

在 ios 平台,數據永久化的存儲方式就那麼幾種,比如說coredata,比如說realm,還有nosql的幾種方案,但是很遺憾,nosql的幾種方案支持的功能都還是太少,這樣就讓對它們的選擇顯得十分雞肋——畢竟,如果是簡單的應用的話,那就還不如其他方案來的方便快捷——雖然nosql是趨勢。

這次我們來談談另一種比較常見的儲存方案——sqlite,這個東西很厲害,它是一個用c實現的無需服務器的sql框架,它就一個文件配合框架就可以實現一個簡單的數據庫了,擁有大部分數據庫的查詢功能,性能也還不錯。

需求

一般使用的話,sqlite的默認配置也是足夠了的,但有一些情況下,我們還是需要更快的體驗——比如作為輸入法的詞庫的時候。很多人覺得,用sqlite很快,但作為輸入法的詞庫就顯然太慢了,難道sqlite就不能更快一步嗎?當然可以,sqlite的默認配之為了適應大部分人的使用環境所以設置的十分保守,我們可以讓它更快。

編譯

Pragma 是 sqlite 特有的一個配置語句,與之配合的有一些對應的參數,我們在連接數據庫後可以對其進行修改,但下次連接的時候,還是需要再次配置的。

你可以在這裡看到完整的所有 Pragma 參數,不過對性能有重大影響的參數也就那麼幾個,不是很多的。

執行 pragma 就像你在 sqlite 裡執行 sql 語句一樣,沒有返回值。

PAGE_SIZE

大小必須是2的倍數,一般來說,現在應該都是默認4096了,但如果不是,那你就手動設置一下,總而言之,你最好把它設置為與你係統硬盤的分頁大小。

同步

關閉同步,數據庫只有在設備突然斷電之類情況下可能導致數據庫損壞——嗯,這種情況,我覺得可以接受。

locking_mode

當不需要同時有多個進程同時訪問數據庫時(我們就在自己的app裡訪問數據庫而已)那就不需要默認的normal,設定鎖定模式為exclusive模式,可以保證同一時間只有一個進程訪問數據庫,這樣可以避免不必要的衝突控制,增加數據庫速度。

journal_mode

日誌能夠保證數據提交的完整性,一旦提交出現問題,數據庫就可以實現回滾。不過,現在大部分情況下ios的穩定性已經足夠,如果你甚至都不會給數據庫寫入內容,那麼乾脆把日誌模式關閉好了。這樣可以大大加快sqlite的速度。

CACHE_SIZE

這個緩存,默認是0,也有不少人推薦1,我建議你自己多測試幾次,我自己的感受是有和沒有區別有點,但大小好像沒啥區別了……

mmap_size

配置內存映射,但實際上好像並沒有開啟,這取決於你的sqlite版本。

query_only

如果你和我一樣只是用來查詢,那麼就開啟這個選項。

單件模式

說完了參數配置,我們再來說說其他方面,比如整體的使用姿勢。如果說你在整個應用中都不會有其他進程訪問數據庫(一般也不應該有),那麼就做一個單件模式,然後保持長鏈接就好了,並沒有必要一直持續地連接和斷開,同時還可以避免你意外地同時去爭奪數據庫資源造成數據的丟失和文件損壞。

比如說,這樣:

索引

恰當地為你需要經常查詢的字段進行索引,並且避免使用太複雜的sql語句以確保查詢會使用索引。一個有效的測試方式是使用 sqlite 內置的 說明 功能查看語句的執行流程,如果其中包含 IDX ,那基本差不多。

使用 explain 來查看sql語句的預計執行過程

避免不恰當的 sql 語句

一般來說,你應該只獲取你要獲取的內容,不要去做 選擇 * 這一類腦殘的語句,同時,在獲取內容的時候,比如你可能寫的是這樣的:

如果是大量查詢,那麼你最好這樣來寫:

使用字段索引來獲取內容,可以避免查找,大大加快取值速度。

創建表

創建表也有優化的地方可以說說,比如如果你的字段能非空,就非空,如果能唯一那自然就最好了!

 

總結

以上就是我在開發落格輸入法的過程中對sqlite的一些性能優化探索,可能並不適用於所有的開發情況。而且高級的編譯優化也還沒有去接觸,希望能夠幫助到你。

延伸閱讀

與Xamarin的iOS SQLite的性能優化

本文由 落格博客 原創撰寫:落格博客 » iOS 平台 SQLite 性能優化

轉載請保留出處和原文鏈接:https://www.logcg.com/archives/2316.html

關於作者

R0uter

如非聲明,本人所著文章均為原創手打,轉載請註明本頁面鏈接和我的名字。

發表評論

您的電子郵件地址不會被公開. 必填字段標 *