9

谁能解释为什么我的插入在 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();
    }
4

3 回答 3

11

我遇到了同样的问题,并找到了合理的解决方法。这需要从 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 毫秒与 120 毫秒。所以我认为更多的细节是有序的。

我们有 3 个表/类/DAO:Parent、ChildWrapper、Child。
关系: Parent 到 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();
    // ...
);

但是插入速度很慢,所以我们尝试callBatchTasks为每个使用过的 DAO 进行嵌套,设置自动提交关闭,startThreadConnection 可能还有其他东西——暂时不记得了。无济于事。

根据我自己的经验和其他类似的帖子,当涉及多个表/DAO 时似乎会出现问题,并且它与具体设备的 Android(或 SQLite)的实现细节有关。

于 2014-12-05T11:50:44.457 回答
3

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

如果您希望将大量数据加载到数据库中,则可以考虑重播数据库转储。看这里:

Android OrmLite 预填充数据库

于 2012-09-27T16:33:36.473 回答
1

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

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

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

于 2012-09-26T19:52:17.950 回答