2012-01-30 71 views
1

我在Android上使用Sqlite &進行簡單的SELECT查詢時性能很差,可能還有一些奇怪的行爲。 SqliteDatabase.query()僅在1 ms內執行我的查詢,但通過Cursor.get*()獲取結果需要150 ms以上才能返回8行!如何提高Sqlite/Android中SELECT查詢的性能?

我試圖在表中查找english所有行其中列word開始與「前綴」(任意字符串),由row列對結果進行排序,並只返回前8個結果。

這裏是我的代碼:

String columns[] = {"word", "rank"}; 
Cursor cursor = mDB.query("english", columns, "word LIKE '" + prefix + "%'", null, null, null, "rank,word", "8"); 

// It takes only 1 ms to get here 

String word = ""; 
int rank = 0; 
if (cursor.moveToFirst()){ 
    do { 
     word = cursor.getString(0); 
     rank = cursor.getInt(1); 
    } 
    while(cursor.moveToNext()); 
} 

cursor.close(); 

// It takes over 150 ms to get here! 

表定義爲english是:

CREATE TABLE en (_id INTEGER PRIMARY KEY, word TEXT, rank INTEGER) 

它包含約65,000項。它也還wordrank指標,有兩個第三指數(我越來越絕望!):

CREATE INDEX "rank" ON "en" ("rank" ASC) 
CREATE INDEX "word" ON "en" ("word" ASC) 
CREATE INDEX "word_rank" ON "en" ("word" ASC, "rank" ASC) 

提前感謝!

回答

2

查詢方法實際上並不檢索所有的數據,當光標在行中移動時,它將檢索它。因此,Cursor.move *()方法比查詢慢。

這種「延遲加載」的概念有助於節省內存,因爲只有在需要時才檢索相關數據。

至於表現,你真的沒有做錯什麼。你在模擬器上試試這個嗎?也許可以在實際設備上試用並測試性能。

+1

嗨凱恩。在發佈我的問題後,我發現瓶頸是cursor.moveToFirst(),這與您所說的有關。我在實際的設備上運行它,但性能非常關鍵,因爲我的應用程序是IME(軟鍵盤),查詢查找字典匹配,因此它必須比鍵盤快。 150+ ms太慢了。 :( – 2012-01-30 03:45:15

+2

Barry,如果你在UI線程上執行查詢,150ms速度太慢,你一定要將數據庫操作移動到一個單獨的線程上,然後將結果發回到UI線程來更新列表。有關此技術的信息請閱讀http://developer.android.com/resources/articles/painless-threading.html – 2012-01-30 03:51:25

+0

我曾考慮過,但如果用戶在查找之前按空格鍵,則會出現同步問題線程發現他的話:自動選擇功能將插入錯誤的單詞,但我會再次看看這種方法,謝謝 – 2012-01-30 04:50:46