2012-09-07 108 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秒。)