任何人都可以解释为什么我的插页在Ormlite中花了这么长时间?在桌面上的一个sqlite事务中执行1,700次插入只需不到一秒钟。但是,当使用Ormlite for Android时,它需要大约70秒,我可以在调试消息中看到每个插入。
当我尝试将插入包装到一个事务中时,它以完全相同的速度运行。我知道Android和Ormlite都有开销,但是,我不希望它那么好。我的代码如下:
this.db = new DatabaseHelper(getApplicationContext());
dao = db.getAddressDao();
final BufferedReader reader = new BufferedReader(new InputStreamReader(getResources().openRawResource(R.raw.poi)));
try {
dao.callBatchTasks(new Callable<Void>() {
public Void call() throws Exception {
String line;
while ((line = reader.readLine()) != null) {
String[] columns = line.split(",");
Address address = new Address();
// setup Address
dao.create(address);
}
return null;
}
});
} catch (SQLException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
答案 0 :(得分:10)
我遇到了同样的问题,并找到了合理的解决方法。插入时间从2秒到150毫秒:
final OrmLiteSqliteOpenHelper myDbHelper = ...;
final SQLiteDatabase db = myDbHelper.getWritableDatabase();
db.beginTransaction();
try{
// do ormlite stuff as usual, no callBatchTasks() needed
db.setTransactionSuccessful();
}
finally {
db.endTransaction();
}
更新:
刚刚在Xperia M2 Aqua(Android4.4 / ARM)上进行了测试,而callBatchTasks()
实际上是更快。 90毫秒vs 120毫秒。所以我认为更多的细节是有序的。
我们有3个表/类/ DAO:Parent,ChildWrapper,Child
关系:父到ChildWrapper - 1到n,ChildWrapper到Child - n到1.
代码是这样的:
void saveData(xml){
for (parents in xml){
parentDao.createOrUpdate(parent);
for (children in parentXml){
childDao.createOrUpdate(child);
childWrapperDao.createOrUpdate(generateWrapper(parent, child));
}
}
}
我在特定的Android4.2 / MIPS机顶盒(STB)上获得了原创速度。
callBatchTasks
是第一个选项,因为这是我们通过所有代码使用的,它运行良好。
parentDao.callBatchTasks(
// ...
saveData();
// ...
);
但是插入速度很慢,所以我们尝试为每个使用过的DAO嵌套callBatchTasks
,设置autocommit off,startThreadConnection以及其他可能的东西 - 此刻不记得了。无济于事。
根据我自己的经验和其他类似的帖子,似乎问题出现在涉及多个表/ DAO时,它与具体设备的Android(或SQLite)的实现细节有关。
答案 1 :(得分:3)
不幸的是,这可能是“预期的”。当我在我的模拟器下执行该数量的插入时,我也获得了类似的性能。批处理任务和关闭自动提交似乎没有帮助。
如果要将大量数据加载到数据库中,可以考虑重放数据库转储。见这里:
答案 2 :(得分:1)
我的猜测是你会慢一点,因为你一次做两个IO任务(至少在上面显示的代码中)。您正在读取文件并写入数据库(这是一个文件)。另外,据我所知,交易应该是合理的规模。 1600似乎是一个非常高的数字。我会从100开始,但是要玩大小。
所以基本上我建议你“插入”你的读取和插入。
读取100行到临时数组,然后插入100.然后读取下一个100,然后插入等。