Как ускорить запись в SQLite БД?

161
27 октября 2017, 11:06

Сейчас я записываю вот так:

public boolean update(List<MyObject> list){
    ContentValues cv = new ContentValues();
    try {
        db.beginTransaction();
        for(int i = 0; i < carlist.size(); i++) {
            cv.put(DataBaseConstants.ID, list.get(i).id);
            cv.put(DataBaseConstants.NUMBER, list.get(i).attributes.Number);
            cv.put(DataBaseConstants.MODEL, list.get(i).attributes.model);
            cv.put(DataBaseConstants.ER, list.get(i).attributes.er);
            cv.put(DataBaseConstants.IN, list.get(i).attributes.in);
            cv.put(DataBaseConstants.HIDDEN, list.get(i).attributes.Hidden);
            //еще несколько строк cv.put
            if (checkExistItem(db, DataBaseConstants.TABLE_NAME, DataBaseConstants.ID + "=?", new String[]{String.valueOf(list.get(i).id)})) {
                db.update(DataBaseConstants.TABLE_NAME, cv, DataBaseConstants.ID + "=?", new String[]{String.valueOf(list.get(i).id)}); 
            } else {
                db.insert(DataBaseConstants.TABLE_NAME, null, cv);
            }
            updateType(db, list.get(i).id, list.get(i).ships.Type);
            updateState(db, list.get(i).id, list.get(i).ships.State);
            cv.clear();
        }
        db.setTransactionSuccessful();
        db.endTransaction();
        Log.d("databaseSpeed","end "+new Date().toString());
        return true;
    } catch (Exception e){
        e.printStackTrace();
        return false;
    }
}
public boolean checkExistItem(SQLiteDatabase db, String tableName, String where, String[] whereParams ){
    Cursor mCursor = db.rawQuery("SELECT "+DataBaseConstants.ANDROID_TABLE_ID+" FROM " + tableName + " WHERE "+ where, whereParams);
    if (mCursor != null && mCursor.getCount() > 0){
        mCursor.close();
        return true;
    } else {
        mCursor.close();
        return false;
    }
}

Список больше 2000 записей, записывается несколько секунд.

В методе update по 100 записей. В этих 100 записях еще есть вложенные листы, которые уходят в соответствующие методы updateType и updateState. Передается лист и запись занимает секунду или 2. В общем получается очень долго. Можно ли ускорить?

Answer 1

У Вашего кода получается как минимум квадратичная сложность (хотя я думаю, что она все же n lg n). Проблема в том, что Вы на каждую итерацию делаете select, что бы выяснить, есть ли указанная запись.

Так как подобный код типичен, то есть готовое решение проблемы - updateWithOnConflict.

Скорее всего вот эти строки

if (checkExistItem(db, DataBaseConstants.TABLE_NAME, DataBaseConstants.ID + "=?", new String[]{String.valueOf(list.get(i).id)})) {
            db.update(DataBaseConstants.TABLE_NAME, cv, DataBaseConstants.ID + "=?", new String[]{String.valueOf(list.get(i).id)}); 
} else {
            db.insert(DataBaseConstants.TABLE_NAME, null, cv);
}

нужно будет поменять на

db.updateWithOnConflict(DataBaseConstants.TABLE_NAME, cv,  DataBaseConstants.ID + "=?", new String[]{String.valueOf(list.get(i).id)}, CONFLICT_REPLACE);

Но это Вам виднее - Вы лучше знаете свою логику. Там есть есть insertWithOnConflict, возможно он будет лучше.

READ ALSO
java.lang.NoSuchMethodError: java.lang.Process.waitFor

java.lang.NoSuchMethodError: java.lang.Process.waitFor

Собственно вот такой код

188
Динамически меняющееся содержимое ExpandableListView

Динамически меняющееся содержимое ExpandableListView

Есть такой код, из которого формируется ExpandableListView:

181
NullPointerException в preparedStatment

NullPointerException в preparedStatment

При добавлении в базу, в с строке preparedStatment = connectionprepareStatement(ADD_USER); ошибка nullPointer как исправить ?

247
ProgressBar в WebView

ProgressBar в WebView

Как отследить нажатие внутри WebView что бы сделать ProgressBar пока грузится другая страничка

215