2011-10-18 22 views
2

當有幾千條結果時,通過Ormlite DAO查詢數據時出現問題。ormlite DAO在android查詢超過幾千條結果時變得非常慢

代碼:

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

當我想要拿分List<Point> pl的大名單當前路線croute我不得不等待像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(); 
    } 
    ... ... 
} 

一些想法我做錯了嗎?

感謝, 託尼

+0

使用普通光標... – Selvin

回答

2

幾件事情嘗試@toni。

  1. 我會考慮存儲你DateDATE_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
+0

Hi @Gray。我實現了你的提議,並使用了dao.iterator(),但我仍然可以獲得1k點/秒的速度。我檢查日誌量表(100,1000,10000,...),這不是一個很大的區別。註釋轉換有問題嗎?我應該使用原始查詢嗎?謝謝。 – toni

+0

這不是僅在DAO創建時發生的註釋轉換。 GC日誌說什麼?很多時間花在那裏?當我回到我的辦公桌時,我會嘗試進行批量測試,看看我是否看到任何東西... – Gray

+0

加載4.3k點時,它顯示了一次'GC_EXPLICIT釋放了10K,50%免費... ...但它顯示:GC_CONCURRENT始終釋放543K,42%免費4439K/7559K,外部0K/512K,暫停3ms + 11ms'循環...謝謝@Gray! – toni