2012-09-07 113 views
0

OutOfMemoryError caused when db4o databse has 15000+ objects如何提高db4o的查询速度?

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

对于100,000个已发布的消息对象,查询大约需要1243毫秒才能返回前20个发布的消息。

现在,我已经在db4o中保存了1,000,000个发布的消息对象。相同的查询花了342,132毫秒。这是非线性高的。

如何优化查询速度?

FYR: timeSent和timeReceived是Indexed字段。 我正在使用SNAPSHOT查询​​模式。 我不使用TA/TP。

+0

你说你只是想要'前20',是你用来订购结果索引在数据库中的信息? – paul

+0

是的,它被索引。我没有使用TA/TP。我正在使用SNAPSHOT查询​​模式。而前20,是因为,我想以分页的方式访问发布的消息。 –

+0

Can Gamlor对此有何评论? –

回答

0

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

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

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

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

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

该方法的参数是如下:

= 13-09-2011十点55分55秒

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

而且我期望在“after”和“before”之间只返回10个PostedMessages。 (我生成的dummyMessage与timeReceived每增加1秒。)