在Android Lollipop上SQLite Query运行速度较慢

时间:2015-04-01 22:46:39

标签: android performance sqlite android-5.0-lollipop

我有一个查询在Gingerbread设备和Jellybean上运行得非常好,但在Lollipop设备上运行速度较慢。我确定查询是正确的并且写得很好,因为它在旧设备上运行良好。

Cursor c;
String query = QUERY STRING;

c = db.rawQuery(query,new String[]{Integer.toString(a),Integer.toString(b)});

Log.e("SQL_QUERY_PROGRESS","1");

while(c.moveToNext()){
    Log.e("SQL_QUERY_PROGRESS","2");
    // Do stuff with data
}

c.close();

在Gingerbread设备上,两条日志消息之间只有0.008秒,而在Lollipop设备上它需要大约8秒,这非常慢。

我能理解的是,棒棒糖设备更新,拥有更多内存,CPU功率等,所以逻辑上要求新设备应该比旧设备更快地运行查询。

Lollipop上使用的Java版本是否存在错误,或者SQLite版本是否会导致速度大幅下降?

我使用了adb shell 并导航到数据库文件并使用Lollipop设备上的sqlite3运行查询,它几乎立即运行,这让我觉得它比SQLite问题更像Java问题。

我完全不知道可能导致延误的因素,所以任何帮助或想法都会受到高度赞赏,所以我可以进一步调查!

2 个答案:

答案 0 :(得分:2)

以下是我解决这个问题的方法。

  1. 首先,您需要确定哪些查询是有问题的。我通过用我自己的方法替换所有rawQuery()调用来完成此操作。它将记录每次查询之间的时间。
  2. private static Cursor runQuery(String query) {
        System.out.println("QUERY: " + query);
        Cursor tmpCursor = DatabaseManager.getInstance().openDatabase().rawQuery(query, null);
        System.out.println("TIME: " + (System.currentTimeMillis() - Main.time));
        Main.time = System.currentTimeMillis();
        return tmpCursor;
    }
    

    检查代码中您怀疑的其他部分的时间。 现在,您将在哪些查询之间看到时间丢失。它实际上是光标逻辑,就像c.moveToFirst()那样昂贵。在那些之后进行时间检查,以便验证。

    1. 当您找到查询后,检查它并检查查询必须经过哪些列。在我的情况下,我有一个列在一个具有大量行的表中的连接。这是下一步所需的专栏:
    2. 为此列创建索引,如下所示:
      CREATE INDEX idx_bibref ON responses(bibreference);
    3. 您可以在终端中运行此测试(sqlite3)或更好地将其放入onUpgrade方法中。 就是这样。现在所有光标方法都会再次运行,就像之前的Android版本一样。


      旧帖子:

      我遇到了同样的问题。我让它在异步任务中运行,所以我可以确认,正如PriestVallon所说,这是在主UI线程上运行,虽然效率不高,但不是导致问题的原因。 它只出现在Lollipop上。请选择手机和仿真器4.4。没有问题。 到目前为止,我的调查结果表明它与游标逻辑有关,而与查询本身无关。例如:

      c.moveToFirst();
      c.moveToNext();
      c.getCount();
      etc... 
      

      通常在使用连接进行更复杂的查询后运行(但我还不能100%确认)。

      也许这会有所帮助。

      (我为回答这个问题而道歉,反对评论,但我没有足够的声誉来发表评论。)

答案 1 :(得分:2)

我遇到了类似的问题 - 一个运行良好的前Lollipop的SQLite查询在Lollipop上运行 lot 更慢。这是一个关于3个连接表的查询,并且花了超过10秒!

在尝试各种各样的事情之后,我发现了问题:Lollipop使用SQLite 3.8,它使用不同的查询优化器,并且出于某种原因,它在其中一个连接中使用了错误的索引。

从我的测试设备上获取数据库副本后,我在查询中使用命令行SQLite工具和“解释查询计划”。比较3.8之前到3.8之后的输出,后者使用了不同且不正确的指数。

从我读到的,在DB上运行“ANALYZE”可能已经修复了它,但由于我并不真正需要它使用的错误索引,我只是删除了索引。现在查询使用正确的索引,查询再次快速。