在SQLite / Android

时间:2018-03-05 08:41:51

标签: android sqlite

简而言之:

使用query()执行23770次SELECT查询并使用Cursor检索结果需要 7秒。通过使用compileStatement()编辑语句并调用simpleQueryForString(),我能够将时间缩短到 1秒。 有没有办法在不使用compileStatement()的情况下获得类似的性能,因为仅当输出为1x1表时,compileStatement()仅限于检索结果?

更多信息:

我有一个Android应用程序,它使用带有以下架构的表的SQLite数据库:

CREATE TABLE testtable(
    id number primary key,
    sentence text not null
);

该表以id为索引 我的应用程序的一部分是将 id 的数组作为输入,并从表 testtable 中检索相应的句子

我开始使用query()方法,花费 7秒 23770 的数组检索句子 ID 秒。 (在7秒内查询23770次)

我试图提高性能,我发现SQLiteStatement compileStatement(String sql)可以通过事先编译语句来提高性能。并且由于SQLiteStatement有一个方法String simpleQueryForString()来检索结果,如果输出是1 x 1表(当前满足我的用例),我使用它。 改善是巨大的。它可以在 1秒中完成相同的 23770 查询。

虽然我现在可以使用它,但是查询可能会变得复杂,输出可能会占用更多行和列,这将使我使用query()方法。

所以我的问题是:有没有办法在不使用compileStatement()的情况下优化查询并获得类似的效果?

这是我正在测试的代码(使用compileStatement()的代码已注释):

public class DBMan extends SQLiteAssetHelper{

    SQLiteDatabase db;

    public DBMan(Context context){
        super(context, "my.db", null, 1);
        db = this.getReadableDatabase();
    }

    public String[] getSentences(Integer[] idList){

        String[] result = new String[idList.length];

        Cursor cur = null;

        long timeStart = System.nanoTime();

        try {
            db.beginTransaction();

            /* SQLiteStatement selStmt = db.compileStatement("SELECT sentence FROM testtable WHERE id=?"); */

            for (int i = 0; i < idList.length; i++) {

                // Querying using compileStatement() and simpleQueryForString()
                /* 
                selStmt.clearBindings();
                selStmt.bindLong(1, idList[i]);
                result[i] = selStmt.simpleQueryForString();
                */

                // Querying using query() and Cursor
                cur = db.query(
                        "testtable",
                        new String[]{"sentence"},
                        "id = ?",
                        new String[]{String.valueOf(idList[i])},
                        null, null, null
                );

                if (cur.moveToFirst()) {
                    result[i] = cur.getString(0);
                }

                if (cur != null) {
                    cur.close();
                }

            }
            db.setTransactionSuccessful();
        }
        finally {
            db.endTransaction();
        }

        long totalTime = System.nanoTime() - timeStart;
        Log.i("MYAPP", "DB total query time: "+totaltime/1000000000.0+" sec");

        return result;
    }
}

我正在使用SQLiteAssetHelper这是SQLiteOpenHelper的扩展名。我正在使用它在首次运行时从assets文件夹复制我的数据库文件,而不是创建它。

我使用了事务,虽然我只做了选择查询,因为它减少了获取和删除的共享锁的数量(see here)。

0 个答案:

没有答案