我在Android上使用ormlite 4.35加载一组对象(及其外来对象)。对于getAllCragsWithLocation()
方法中的时序,它(在模拟器中)需要16到19秒。
数据库中有590个Crags,40个没有位置。
记录了几行,例如
03-19 11:03:54.441: I/dalvikvm(1156): Jit: resizing JitTable from 1024 to 2048
03-19 11:03:55.531: D/dalvikvm(1156): GC_CONCURRENT freed 544K, 37% free 5174K/8199K, external 731K/1109K, paused 6ms+11ms
我应该以另一种方式加载对象吗?在sqlite3命令行运行查询大约需要100秒......
public List<Crag> getAllCragsWithLocation() {
Log.i(TAG,"beginning db calls");
long startQuery = System.currentTimeMillis();
QueryBuilder<Crag,Integer> queryBuilder = helper.getCragDao().queryBuilder();
List<Crag> results = new ArrayList<Crag>();
try {
queryBuilder.where().isNotNull("location_id");
Log.i(TAG,queryBuilder.prepareStatementString());
PreparedQuery<Crag> preparedQuery = queryBuilder.prepare();
results = helper.getCragDao().query(preparedQuery);
} catch (android.database.SQLException e) {
Log.e(TAG,e.toString());
} catch (SQLException e) {
Log.e(TAG,e.toString());
}
Log.i(TAG,"ending query after "+((System.currentTimeMillis()-startQuery)/1000)+" seconds");
return results;
}
crag对象(简化)是:
@DatabaseTable
public class Crag {
public Crag() {
//ormlite requires a no-arg constructor?
guidebooks = new ArrayList<Guidebook>();
}
@DatabaseField(id=true) private int id;
@ForeignCollectionField(eager = true)
private Collection<Guidebook> guidebooks;
@DatabaseField(foreign=true, foreignAutoRefresh = true, index=true)
private uk.co.bmc.rad.models.Location location;
@DatabaseField(foreign=true,foreignAutoRefresh=true)
private SubRegion subRegion;
}
外来对象比Crag更简单。出于显示的目的,仅在从数据库加载对象的位置处需要位置,但是在比较相等时我使用外来对象...
重复getAllCragsWithLocation()
的回复以准备添加到MapOverlay
。该过程的时间不到一秒钟。
更新: 我刚刚交换了DB4O进行比较,并且通过比较基本上立即加载了所有的碎片,所以我想我会接受它。
更新更新: 而不是快速交换DB4O,我花了更多的时间来比较这两者。
在JUnit 3 AndroidTestCase中,如果我将一条记录插入数据库然后直接查询,那么ORMLite和DB4O大约需要一秒钟(总计)插入并返回该对象。
如果我运行我的进程以插入590个对象,则ORMLite大约需要24秒,而DB40需要大约40秒。
在插入之后,如果我调用getAllCragsWithLocation()然后调用getAllCrags(),DB40需要7秒然后0秒才能返回一个Crags列表,所以我猜它有一个缓存可以加速第二个查询
虽然ORMLite在两个查询中花费大约7秒钟。
所以实际上它很少
更新更新: 今天抓住了Transformer Prime,只需运行应用程序就可以在1秒内加载峭壁,而模拟器上则为7秒。
因为我已经设法使用grok ormlite的查询语法;可以回退到原始sql并且sqlite表结构更可转移我将坚持使用ormlite而不是db4o。
答案 0 :(得分:4)
我真的很惊讶它花了很长时间。
@ForeignCollectionField(eager = true)
private Collection<Guidebook> guidebooks;
@DatabaseField(foreign=true, foreignAutoRefresh = true, index=true)
private uk.co.bmc.rad.models.Location location;
@DatabaseField(foreign=true,foreignAutoRefresh=true)
private SubRegion subRegion;
这些字段中的每一个都会生成另一个需要时间的数据库查询,尽管我不希望秒。使用JOIN
来满足渴望获取的远程对象时,ORMLite并不聪明。
尝试的一件事是在生成DAO实现时使用table-config进程来解决Android的dog,dog慢速反射实现。请参阅文档:
如果你弄清楚我会很好奇,虽然我明白你是否需要切换到其他一些包才能开始工作。
答案 1 :(得分:-1)
我认为您应该考虑使用ContentProvider。我已经创建了一个操作2k行的应用程序但是在模拟器上不到10秒就完成了查询和对象重新生成