0

当 db4o 数据库有 15000 多个对象时导致 OutOfMemoryError

我的问题是参考我之前的问题(上)。对于相同的 PostedMessage 模型和相同的查询。

对于 100,000 个 PostedMessage 对象,查询需要大约 1243 毫秒才能返回前 20 个 PostedMessage。

现在,我在 db4o 中保存了 1,000,000 个 PostedMessage 对象。相同的查询花费了 342,132 毫秒。这是非线性的高。

如何优化查询速度?

FYR:timeSent 和 timeReceived 是索引字段。我正在使用 SNAPSHOT 查询模式。我没有使用 TA/TP。

4

2 回答 2

0

你对结果进行排序吗?不幸的是 db4o 不使用索引进行排序/orderBy。这意味着它将使用 O(n*log(n)) 运行常规排序算法。它不会线性缩放。

db4o 也不支持 TOP 运算符。这意味着即使没有排序,将 id 复制到结果集中也需要相当多的时间,即使您之后从未阅读过实体。

因此,除了尝试使用一些减少结果大小的标准外,没有真正好的解决方案。

一些冒险的人可能会使用不同的查询评估,但个人不建议这样做。

于 2012-09-13T11:50:18.190 回答
0

@Gamlor不,我根本没有排序。代码如下:

public static ObjectSet<PostedMessage> getMessagesBetweenDates(
        Calendar after,
        Calendar before,
        ObjectContainer db) {

    if (after == null || before == null || db == null) {
        return null;
    }
    Query q = db.query(); //db is pre-configured to use SNAPSHOT mode.
    q.constrain(PostedMessage.class);
    Constraint from = q.descend("timeRecieved").constrain(new Long(after.getTimeInMillis())).greater().equal();
    q.descend("timeRecieved").constrain(new Long(before.getTimeInMillis())).smaller().equal().and(from);
    ObjectSet<EmailMessage> results = q.execute();
    return results;
}

该方法的参数如下:

之后 = 2011 年 9 月 13 日 10:55:55

之前 = 2011 年 9 月 13 日 10:56:10

而且我希望在“之后”和“之前”之间只返回 10 个 PostedMessages。(我正在生成虚拟 PostedMessage,timeReceived 每次增加 1 秒。)

于 2012-09-13T15:31:10.380 回答