查询数千个结果时,android中的Ormlite DAO变得非常慢
Posted
技术标签:
【中文标题】查询数千个结果时,android中的Ormlite DAO变得非常慢【英文标题】:Ormlite DAO in android getting really slow when querying more than few thousand results 【发布时间】:2011-12-10 07:41:24 【问题描述】:当有几千个结果时,通过 Ormlite DAO 查询数据时遇到问题。
代码:
List<Point> pl = db.getPointsDAO().queryBuilder().where().
eq("route_id", croute).query();
当我想获得当前路线 croute
的大量点列表 List<Point> pl
时,我必须等待 40 秒才能获得 40.000 点。
Point.class 在哪里:
@DatabaseTable(tableName = "points")
public class Point extends BaseEntity
@DatabaseField(generatedId = true)
private Integer point_id;
@DatabaseField(canBeNull = false)
...
@DatabaseField(canBeNull = false)
private Double dose;
@DatabaseField(dataType=DataType.DATE_STRING, format="yyyy-MM-dd HH:mm:ss")
public Date date;
@DatabaseField(canBeNull=true,foreign=true)
private Route route;
public Point()
super();
;
... ...
Route.class 是:
@DatabaseTable(tableName = "routes")
public class Route extends BaseEntity
@DatabaseField(generatedId = true)
private Integer route_id;
@DatabaseField(canBeNull = true)
private String name;
@ForeignCollectionField(eager = false)
ForeignCollection<Point> points;
public Route()
super();
... ...
一些想法我做错了什么?
谢谢, 托尼
【问题讨论】:
【参考方案1】:尝试@toni 的几件事。
-
我会考虑将您的
Date
存储为 DATE_LONG
而不是一个字符串,这样可以节省 40k 字符串/日期转换。
@Selvin 是对的,如果有某种方法可以让您遍历数据库,这可能会降低您的内存需求并加快速度。请参阅 ORMLite 中的 dao.iterator()。
我会使用 int
和 double
原语来降低每个对象的 GC,尽管我怀疑这会产生很大的不同。
尝试加载 1000 点,然后是 10000 点,然后是 20000 点,看看在某个时间点性能是否下降。这将告诉您您正在达到内存限制。
使用adb logcat
实用程序查看您是否可以查看GC 时间,看看您是否只是在破坏收集器。你可以做的任何事情来降低你的内存使用量都会有所帮助。寻找类似的行:GC_EXPLICIT freed 4140 objects / 216560 bytes in 114ms虽然我怀疑这是问题所在,但您会丢失索引吗?尝试在外部
route
字段上添加index = true
。
【讨论】:
嗨@Gray。我实施了您的建议并且也使用了 dao.iterator() 但我仍然获得了 1k 点/秒的速度。我检查了对数刻度(100,1000,10000,...),差别不大。注释转换有问题吗?我应该使用原始查询吗?谢谢。 这不是注释转换,它只发生在 DAO 创建时。 GC 日志说了什么?在那里度过了很多时间?回到办公桌后,我会尝试进行批量测试,看看是否有任何发现...... 在加载 4.3k 点时,它显示一次GC_EXPLICIT freed 10K, 50% free
... 但它显示:GC_CONCURRENT freed 543K, 42% free 4439K/7559K, external 0K/512K, paused 3ms+11ms
一直...循环...谢谢@Gray!
这看起来你只是在创建太多对象@toni。在查看 ORMLite 时,它看起来只会创建 Point
对象——除了底层 android API 所做的那些之外,没有临时对象。我们还没有解决您的问题,对吧?
我不懂你。那么这个加载数据的速度是正常的吗?以上是关于查询数千个结果时,android中的Ormlite DAO变得非常慢的主要内容,如果未能解决你的问题,请参考以下文章