2011-08-25 94 views
4

很慢,我有相當大的數據庫,我需要查詢來獲取在Android上一個ListView一些數據和現在。數據庫大約5MB,它存儲在SD卡上。它在2個表中有60k條記錄。問題是,查詢數據庫,從一個特定的列的所有記錄需要可笑的很長一段時間 - 就像兩個模擬器和我的電話幾分鐘。我已經嘗試了一切 - 將這些數據存儲在平面文件中,xml - sqlite是我最後的希望。這是我使用打開數據庫和查詢它的類:SQLite的查詢在Android

public class DataHelper { 

    private static final int DATABASE_VERSION = 1; 
    private static final String TABLE_NAME = "TableName"; 
    private Context context; 
    private SQLiteDatabase db; 
    private SQLiteStatement insertStmt; 

    public DataHelper(Context context) { 
     this.context = context; 
     OpenHelper openHelper = new OpenHelper(this.context); 
     // this.db = openHelper.getReadableDatabase(); 

     this.db = SQLiteDatabase.openDatabase(
       Environment.getExternalStorageDirectory() 
         + "/myDB.db", null, 
       SQLiteDatabase.NO_LOCALIZED_COLLATORS); 
     // this.insertStmt = this.db.compileStatement(INSERT); 
    } 

    public void deleteAll() { 
     this.db.delete(TABLE_NAME, null, null); 
    } 

    public List<String> selectBrands() { 
     List<String> list = new ArrayList<String>(); 
     Cursor cursor = this.db.query(TABLE_NAME, new String[] { "ColumnName" }, 
       null, null, null, null, null); 
} 
     if (cursor.moveToFirst()) { 
      do { 
       if (!(list.contains(cursor.getString(0)))) { 
        list.add(cursor.getString(0)); 

       } 

      } while (cursor.moveToNext()); 
     } 
     if (cursor != null && !cursor.isClosed()) { 
      cursor.close(); 
     } 
     return list; 
    } 

    private static class OpenHelper extends SQLiteOpenHelper { 
     OpenHelper(Context context) { 
      super(context, null, null, DATABASE_VERSION); 

     } 

     @Override 
     public void onCreate(SQLiteDatabase db) { 

     } 

     @Override 
     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 

      onCreate(db); 
     } 
    } 

,並把對ListView的一部分:

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    try { 
     ctxContext = this.getApplicationContext(); 

     lView = (ListView) findViewById(R.id.ListView01); 

     lView.setTextFilterEnabled(true); 

     ParseSQLITETask task = new ParseSQLITETask(); 
     task.execute(null); 

    } catch (Exception e) { 
     LogErr(e.getMessage()); 
    } 

} 

private class ParseSQLITETask extends AsyncTask<Void, Void, Void> { 
    @Override 
    protected Void doInBackground(Void... urls) { 
     try { 

      DataHelper dHelper = new DataHelper(getApplicationContext()); 
      list = (ArrayList<String>) dHelper.selectBrands(); 

     } catch (Exception e) { 
      LogErr(e.getMessage()); 

     } 
     return null; 

    } 

    @Override 
    protected void onProgressUpdate(Void... progress) { 

    } 

    @Override 
    protected void onPostExecute(Void result) { 
     try { 

      lView.setAdapter(new ArrayAdapter<String>(ctxContext, 
        R.layout.list_item, list)); 
     } catch (Exception e) { 
      LogErr(e.getMessage()); 

     } 
    } 

} 

回答

10

您檢索整個記錄集,並將其轉換爲ArrayList。不要這樣做。將光標移回並使用適當的適配器(如SimpleCursorAdapter)。

編輯:您可能還需要考慮creating an index該列,因爲它可能會加快您的檢索時間。

+1

使用該列過濾WHERE子句時,否則也不會做太多的索引將加快查詢。將所有內容放入ArrayList中肯定會很慢。 – satur9nine

+0

非常感謝@Femi這個想法。 –

5

未經測試,我希望你list.contains吃了很多時間。您應該可以使用SELECT DISTINCT刪除數據庫庫中的重複項。

編輯:費米是正確的,你可能並不需要的所有記錄List反正。光標和/或適配器可能就足夠了。還要考慮是否可以以任何方式縮小結果(例如WHERE子句)。

0

這裏是我最後使用的代碼,如果任何人有類似的問題:

public class DataHelper { 

    private static final int DATABASE_VERSION = 1; 
    private static final String TABLE_NAME = "TableName"; 
    private Context context; 
    private SQLiteDatabase db; 

    public static final String ColName = "ColumnName"; 
    public static final String KEY_ID = "_id"; 

    public DataHelper(Context context) { 
     this.context = context; 
     OpenHelper openHelper = new OpenHelper(this.context); 

     this.db = SQLiteDatabase.openDatabase(
       Environment.getExternalStorageDirectory() 
         + "/myDB.db", null, 
       SQLiteDatabase.NO_LOCALIZED_COLLATORS); 

    } 

    public void deleteAll() { 
     this.db.delete(TABLE_NAME, null, null); 
    } 

    public Cursor selectBrandsCursor() { 

     String[] columns = new String[] { ColName, KEY_ID }; 
     Cursor cursor = this.db.rawQuery("SELECT " + ColName + ", " + KEY_ID 
       + " FROM " + TABLE_NAME + " GROUP BY " + ColName + ";", null); 

     return cursor; 
    } 

    private static class OpenHelper extends SQLiteOpenHelper { 
     OpenHelper(Context context) { 
      super(context, null, null, DATABASE_VERSION); 

     } 

     @Override 
     public void onCreate(SQLiteDatabase db) { 

     } 

     @Override 
     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 

      onCreate(db); 
     } 
    } 
} 

的作品真的很好,速度快了很多,重複的自由,感謝馬修和費米的建議。