【问题标题】:How to increase query speed in db4o?如何提高 db4o 中的查询速度?
【发布时间】:2012-09-01 09:52:29
【问题描述】:

OutOfMemoryError caused when db4o databse has 15000+ objects

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

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

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

如何优化查询速度?

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

【问题讨论】:

  • 你说你只想要'前20',是你用来排序在数据库中索引的结果的信息吗?
  • 是的,它已编入索引。我没有使用 TA/TP。我正在使用 SNAPSHOT 查询模式。前 20 个是因为,我想以分页方式访问 PostedMessages。
  • Gamlor 可以评论这个吗?

标签: database optimization db4o large-data


【解决方案1】:

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

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

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

一些喜欢冒险的人可能会使用不同的query evaluation,但个人不建议这样做。

【讨论】:

    【解决方案2】:

    @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;
    }
    

    该方法的参数如下:

    之后 = 13-09-2011 10:55:55

    之前 = 13-09-2011 10:56:10

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

    【讨论】:

      猜你喜欢
      • 2019-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-29
      • 1970-01-01
      • 2021-11-17
      • 2019-12-21
      • 1970-01-01
      相关资源
      最近更新 更多