9

Ormlite で挿入に時間がかかる理由を誰か説明できますか? デスクトップで 1 回の sqlite トランザクションで 1,700 回の挿入を実行すると、1 秒もかかりません。ただし、Ormlite for Android を使用すると、約 70 秒かかり、デバッグ メッセージに各挿入が表示されます。

挿入を 1 つのトランザクションにラップしようとすると、まったく同じ速度になります。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()実際には高速です。90ms 対 120ms。ですので、詳細は適当だと思います。

Parent、ChildWrapper、Child の 3 つのテーブル/クラス/DAO があります。
関係: 親から ChildWrapper - 1 から n、ChildWrapper から子 - 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

残念ながら、これは「予想される」可能性があります。エミュレーターでその数の挿入を行うと、同様のパフォーマンスが得られます。バッチタスクと自動コミットのオフは役に立たないようです。

大量のデータをデータベースにロードする場合は、代わりにデータベースダンプを再生することを検討してください。ここを参照してください:

AndroidOrmLiteはデータベースに事前入力します

于 2012-09-27T16:33:36.473 に答える
1

私の推測では、一度に 2 つの IO タスクを実行しているため (少なくとも上記のコードでは)、多少速度が低下していると思われます。ファイルから読み取り、データベース (ファイル) に書き込みます。また、私が理解していることから、トランザクションは妥当なサイズでなければなりません。1600 は非常に高い数値のように思えます。私は 100 から始めますが、サイズをいじってみます。

したがって、基本的には、読み取りと挿入を「チャンク」することをお勧めします。

一時配列に 100 行を読み取り、その 100 行を挿入します。次に、次の 100 行を読み取り、挿入します。

于 2012-09-26T19:52:17.950 に答える