【问题标题】:Ormlite DAO in android getting really slow when querying more than few thousand results查询数千个结果时,android中的Ormlite DAO变得非常慢
【发布时间】:2011-12-10 07:41:24
【问题描述】:

当有几千个结果时,通过 Ormlite DAO 查询数据时遇到问题。

代码:

List<Point> pl = db.getPointsDAO().queryBuilder().where().
            eq("route_id", croute).query();

当我想获得当前路线 croute 的大量点列表 List&lt;Point&gt; 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();
    }
    ... ...
}

一些想法我做错了什么?

谢谢, 托尼

【问题讨论】:

    标签: android performance dao ormlite


    【解决方案1】:

    尝试@toni 的几件事。

    1. 我会考虑将您的 Date 存储为 DATE_LONG 而不是一个字符串,这样可以节省 40k 字符串/日期转换。
    2. @Selvin 是对的,如果有某种方法可以让您遍历数据库,这可能会降低您的内存需求并加快速度。请参阅 ORMLite 中的 dao.iterator()
    3. 我会使用 intdouble 原语来降低每个对象的 GC,尽管我怀疑这会产生很大的不同。
    4. 尝试加载 1000 点,然后是 10000 点,然后是 20000 点,看看在某个时间点性能是否下降。这将告诉您您正在达到内存限制。
    5. 使用adb logcat 实用程序查看您是否可以查看GC 时间,看看您是否只是在破坏收集器。你可以做的任何事情来降低你的内存使用量都会有所帮助。寻找类似的行:
      GC_EXPLICIT freed 4140 objects / 216560 bytes in 114ms
    6. 虽然我怀疑这是问题所在,但您会丢失索引吗?尝试在外部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 所做的那些之外,没有临时对象。我们还没有解决您的问题,对吧?
    • 我不懂你。那么这个加载数据的速度是正常的吗?
    猜你喜欢
    • 1970-01-01
    • 2020-11-21
    • 1970-01-01
    • 1970-01-01
    • 2017-04-29
    • 2021-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多