3

次のコードを使用してSQLiteデータベースに保存した文字列が約15,000個あります。

 void addKey(String key, String value, String table) {
        SQLiteDatabase db = this.getWritableDatabase();

        ContentValues values = new ContentValues();
        values.put(KEY_KEY, key); // Contact Name
        values.put(KEY_VALUE, value); // Contact Phone

        // Inserting Row
        db.insert(table, null, values);
        db.close(); // Closing database connection

    }

次に、次の方法を使用してそのデータベースを検索し、探しているキーimに一致する文字列を選択します。

public String searchKeyString(String key, String table){
        String rtn = "";
        Log.d("searchKeyString",table);

            // Select All Query
            String selectQuery = "SELECT  * FROM " + table;

            SQLiteDatabase db = this.getWritableDatabase();
            Cursor cursor = db.rawQuery(selectQuery, null);

            // looping through all rows and adding to list
            if (cursor.moveToFirst()) {
                do {
                    Log.d("searchKeyString","searching");

                    if(cursor.getString(1).equals(key)) 
                        rtn = rtn + "," + cursor.getString(2);
                } while (cursor.moveToNext());
            }
            cursor.close();
            db.close();
            Log.d("searchKeyString","finish search");

        return rtn;
    }

目標は、ユーザーがキープボードに入力しているときにこれをリアルタイムで実行することです。そのため、応答時間が重要であり、現在の状態では、検索を実行するのに1秒以上かかります。

最初にすべての項目を配列リストに読み込んで、より高速なものを並べ替えることを検討しましたが、そのサイズの配列リストはメモリの問題を引き起こす可能性があると思いました。データベース内のこれらのエントリを検索するための最良の方法は何ですか?

4

4 に答える 4

8

あなたができることがいくつかあります...

  • 最後までStringBuilderへの戻りを変更します。
  • 読み取り可能なバージョンのデータベースのみを使用してください(ただし、おそらく大きな違いはありません)
  • データベースの新しいインスタンスを毎回取得するのではなく、不要になるまで開いたままにします。
  • SQLクエリの「WHERE」引数を使用して、必要なものだけをクエリします。

いくつかの変更を加えた以下のコードを参照してください。

// move this somewhere else in your Activity or such
SQLiteDatabase db = this.getReadableDatabase();

public String searchKeyString(String key, String table){
    StringBuilder rtn = new StringBuilder();
    Log.d("searchKeyString",table);

        // Select All Query
        String selectQuery = "SELECT  * FROM " + table + " WHERE KEY_KEY=?";

        Cursor cursor = db.rawQuery(selectQuery,  new String[] {key});
        // you can change it to
        // db.rawQuery("SELECT * FROM "+table+" WHERE KEY_KEY LIKE ?", new String[] {key+"%"});
        // if you want to get everything starting with that key value

        // looping through all rows and adding to list
        if (cursor.moveToFirst()) {
            do {
                Log.d("searchKeyString","searching");

                rtn.append(",").append(cursor.getString(2));
            } while (cursor.moveToNext());
        }
        cursor.close();
        Log.d("searchKeyString","finish search");

    return rtn.toString();
}

これをユーザーにとって「リアルタイム」で実行したい場合でも、これを別のスレッドまたはASyncTaskに移動する必要があります。そうしないと、問題が発生します。

于 2012-12-04T05:14:45.587 に答える
2

SELECT * FROM your-table LIMIT 50たとえば、の使用を検討する必要があります。また、ビューに「戻る」、「次へ」の2つのボタンを配置できます。すべてのページに最大50個のアイテムがある場合、ユーザーはページ1にいて、[次へ]をタップすると、次のクエリを使用できます。

SELECT * FROM your-table LIMIT 50 OFFSET 50

テーブルにほとんどのテキストデータが含まれていて、検索をアプリに深く統合したい場合は、FTSで仮想テーブルを使用することを検討してください。

于 2012-12-04T04:44:33.083 に答える
0

よくわかりませんが、選択した文字列を1つずつクエリする方が速いかもしれません。

public String searchKeyString(String key, String table){
    String rtn = "";
    Log.d("searchKeyString",table);

    // Select All Query
    String selectQuery = "SELECT  * FROM " + table + "WHERE column_1 = " + key;

    SQLiteDatabase db = this.getWritableDatabase();
    Cursor cursor = db.rawQuery(selectQuery, null);

    // looping through all rows and adding to list
    if (cursor.moveToFirst()) {
        rtn = rtn + "," + cursor.getString(2);
    }
    cursor.close();
    db.close();
    Log.d("searchKeyString","finish search");

    return rtn;
}

編集:

これらのカスタムキーボードアプリがどのように機能するかはわかりませんが、AutoCompleteTextViewsアダプターに接続されています。同様に簡単にを作成してcursorAdapter、オートコンプリートビューをそれにフックすることができます。

http://www.outofwhatbox.com/blog/2010/11/android-autocompletetextview-sqlite-and-dependent-fields/

http://www.opgenorth.net/blog/2011/09/06/using-autocompletetextview-and-simplecursoradapter-2/

于 2012-12-04T04:21:23.680 に答える
0

sqliteにハードリフティングを実行させます。

まず、検索しているフィールドにインデックスを追加します(まだ持っていない場合)。次に、手動のテーブルスキャンですべてのSELECTを実行するのではなく、フォームでクエリを使用します

SELECT column_value
  FROM my_table
 WHERE column_key LIKE "ABC%"

これは最小量のデータを返し、SQLエンジンはインデックスを使用します。

于 2012-12-04T04:37:02.373 に答える