3

我有大量字符串,大约 15,000 个,我使用以下代码存储在 SQLite 数据库中:

 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

    }

然后我使用以下方法搜索该数据库,以挑选出与我正在寻找的键匹配的任何字符串:

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;
    }

目标是在用户在保留板上输入时实时执行此操作,因此响应时间是关键,而现在它的状态需要一秒钟以上才能完成搜索。

我最初考虑将所有项目读入一个数组列表并通过可能更快的排序,但我认为该大小的数组列表可能会导致内存问题。在我的数据库中搜索这些条目的最佳方法是什么?

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。您可以在视图上放置两个按钮“返回”、“下一步”。如果每个页面最多有 50 个项目,用户在第 1 页,他点击“下一步”,那么您可以使用以下查询:

SELECT * FROM your-table LIMIT 50 OFFSET 50

如果您的表格包含大部分文本数据,并且您希望将搜索深入集成到您的应用程序中,请考虑使用带有FTS的虚拟表格。

于 2012-12-04T04:44:33.083 回答
0

让 sqlite 做艰苦的工作。

首先,如果您还没有索引,请向您要搜索的字段添加索引。其次,不要使用手动表扫描执行 SELECT all,而是使用表单中的查询

SELECT column_value
  FROM my_table
 WHERE column_key LIKE "ABC%"

这样返回的数据量最少,sql引擎使用索引。

于 2012-12-04T04:37:02.373 回答
0

我不知道更好,但也许对选定的字符串逐个进行查询会更快。

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 回答