2012-06-09 68 views
1

我有一個活動中的代碼來從數據庫中收集數據。活動打開需要5秒鐘。沒有這個,活動需要2秒鐘才能打開。有沒有一種方法來優化此代碼?Android的SQL遊標很慢

所有數組(包括循環中的一個:arr_calllog_name0)在我的手機上有61個項目。在模擬器中它很快,有6個項目。

for (int i=0; i<arr_calllog_name0.size(); i++) 
    { 


     Cursor crname = info.getAllTitles_Stats2A(arr_calllog_name0.get(i), "1", d1, d2); 
     crname.moveToFirst(); 
     count_in = crname.getInt(0); 
     arr_calllog_numberin0.add(String.valueOf(count_in)); 



     Cursor crname2 = info.getAllTitles_Stats2A(arr_calllog_name0.get(i), "2", d1, d2); 
     crname2.moveToFirst(); 
     count_out = crname2.getInt(0); 
     arr_calllog_numberout0.add(String.valueOf(count_out)); 



     Cursor crname3 = info.sumAllTitles_StatsA(arr_calllog_name0.get(i), "1", d1, d2); 
     crname3.moveToFirst(); 
     sum_in = crname3.getInt(0); 
     arr_calllog_durationin0.add(String.valueOf(sum_in)); 



     Cursor crname4 = info.sumAllTitles_StatsA(arr_calllog_name0.get(i), "2", d1, d2); 
     crname4.moveToFirst(); 
     sum_out = crname4.getInt(0); 
     arr_calllog_durationout0.add(String.valueOf(sum_out)); 

    } 

信息被聲明爲HotOrNot info = new HotOrNot(ChartsDuration.this);其中HotOrNot是包含DbHelper類擴展SQLiteOpenHelper類。

一個查詢(另一種是幾乎相同)

public Cursor getAllTitles_Stats2A(String name, String type, String date1, String date2) { 
     return ourDatabase.rawQuery("SELECT COUNT(*) FROM " + DATABASE_TABLE + " WHERE " + KEY_DATE + " BETWEEN '" + date1 + "'" + " AND '" + date2 + "'" + " AND " + KEY_NAME + " = '" + name + "'" + " AND " + KEY_TYPE + " = '" + type + "'" + " COLLATE NOCASE", null); 
    } 

的DATABASE_TABLE有我的電話500個項目。

+0

如果您對每個「item」(無論「item」是什麼)執行四個查詢,並且有61個「items」,那可能會很慢。然而,因爲我們不知道'info'是什麼,所有這些查詢都是什麼,你正在查詢什麼,'arr_calllog_name0'是什麼,爲什麼你認爲你需要運行所有這些查詢,等等,這是不可能的任何人都可以真正幫助你。 – CommonsWare

+0

我已更新我的問題。 – erdomester

回答

2

永遠不要以這種方式使用遊標。遊標是寶貴的(遊標是一個數據表而不是指針),因此它們在CPU時間方面創建起來很昂貴。你的例子有兩個非常嚴重的問題。

  1. 不要運行查詢在for循環
  2. 始終關閉遊標,當你用它完成

你更有可能贏得成功,如果你能找到一個方法來做到這一點使用一個JOIN,但沒有更多的信息,很難給出一個更確切的解決方案,你的問題。

+0

for循環中的查詢是不好的做法,我同意。我設法做到沒有for循環,但它沒有幫助。爲什麼要關閉遊標?當我不關閉數據庫時,出現錯誤。但是在遊標的情況下。 – erdomester

+0

遊標使用資源(即吞噬內存)。未能關閉它們將導致資源問題。請注意,如果您使用的是託管遊標,那麼該活動應該爲您關閉此功能。我覺得自己管理它們會更好。至於數據庫錯誤,這是每個活動打開和關閉數據庫的常見弊端。這不是致命的,但如果你真的想避免它,你需要通過覆蓋默認應用程序類來實現訪問數據庫的單例模型。你需要研究這個。 – Merlin