我有一个查询在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问题。
我完全不知道可能导致延误的因素,所以任何帮助或想法都会受到高度赞赏,所以我可以进一步调查!
答案 0 :(得分:2)
以下是我解决这个问题的方法。
rawQuery()
调用来完成此操作。它将记录每次查询之间的时间。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()
那样昂贵。在那些之后进行时间检查,以便验证。
CREATE INDEX idx_bibref ON responses(bibreference);
您可以在终端中运行此测试(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”可能已经修复了它,但由于我并不真正需要它使用的错误索引,我只是删除了索引。现在查询使用正确的索引,查询再次快速。