Ormlite Android批量插入

时间:2012-09-26 19:27:21

标签: android sqlite transactions ormlite

任何人都可以解释为什么我的插页在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();
    }

3 个答案:

答案 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)

不幸的是,这可能是“预期的”。当我在我的模拟器下执行该数量的插入时,我也获得了类似的性能。批处理任务和关闭自动提交似乎没有帮助。

如果要将大量数据加载到数据库中,可以考虑重放数据库转储。见这里:

  

Android OrmLite pre-populate database

答案 2 :(得分:1)

我的猜测是你会慢一点,因为你一次做两个IO任务(至少在上面显示的代码中)。您正在读取文件并写入数据库(这是一个文件)。另外,据我所知,交易应该是合理的规模。 1600似乎是一个非常高的数字。我会从100开始,但是要玩大小。

所以基本上我建议你“插入”你的读取和插入。

读取100行到临时数组,然后插入100.然后读取下一个100,然后插入等。