Массовая вставка SQLite (100-1000 строк за раз) с использованием db.ExecSQL или с помощью using statement.bind (у меня есть 20000 записей и 7 столбцов)

#android #sqlite #bulkinsert #query-performance

#Android #sqlite #bulkinsert #производительность запроса

Вопрос:

Необходимо вставить массовые данные в SQLite (по крайней мере, 100-500 записей за раз…имея 7 столбцов, каждая строка будет иметь 7 значений)

Используя statment.bind, пожалуйста, предложите, если что-то не так, и hw реализовать с помощью db.ExecSQL пакетную вставку

     SQLiteDatabase db = DBHelper.getWritableDatabase();
    String  str = "INSERT INTO DBAdapter.KEY_BD1_DB_NAME(a, b, c, d, e, f,g) VALUES(?, ?, ?, ?, ?, ?,?)";
    SQLiteStatement statement = db.compileStatement(str);


    db.beginTransactionNonExclusive();

    try {


        for (int i=0;i<arraylist.length;i  )
        {

            statement.bindLong(1, id);
            statement.bindLong(2, alist[i]);
            statement.bindLong(3, blist[i]);
            statement.bindString(4, strTStamp[0]);
            statement.bindString(5, strTStamp[1]);
            statement.bindLong(6, j);
            statement.bindLong(7, tstamp);




            if (alist.size>100)
            {
                if(count==100)
                {
                    statement.executeInsert();
                    statement.clearBindings();
                    count=0;
                }
                else
                {
                    count  ;
                }


            }



        }
        statement.executeInsert();
        statement.clearBindings();
        db.setTransactionSuccessful();


        Log.d("INSERT","Done");
        return true;
    } catch (SQLException ex) {
        Log.w("SqlErr", "At kkr : "   ex.toString());
        return false;
    }finally {
        db.endTransaction();
        db.close();
    }
  

Комментарии:

1. что-то не так с вашим кодом? работает ли это? в чем вопрос? пожалуйста, уточните, с какой проблемой вы столкнулись, что вы пробовали и т. Д

2. Вышеупомянутый код будет выполнять настройку производительности для массовой вставки ??… требуется время для вставки данных в db …..hv для вставки по крайней мере 100 строк за раз

3. сколько времени это занимает? сколько времени приемлемо?

4. Ваша логика выглядит нормально (за исключением этого count материала). Подготовьте инструкцию insert, запустите транзакцию, повторно используйте эту подготовленную инструкцию каждый раз в цикле с новыми привязками значений до завершения, зафиксируйте. Лучшего волшебного способа не существует — это уже лучший способ. Единственное, что я могу предложить, это, возможно, пропустить clearBindings() вызов и привязать только значения, которые не будут меняться с каждой строкой один раз, вместо того, чтобы многократно выполнять это в цикле.

5. Около 80-90 секунд

Ответ №1:

Вы можете вставлять только одну строку за раз. Итак, удалив странные вещи из вашего кода и включив бит, который я упомянул в комментарии о привязке постоянных значений только один раз (Отказ от ответственности: это сработало бы на C; не уверен на 100% в привязках java / Android), стандартный подход к вставке группы данных должен выглядеть примерно так:

 SQLiteDatabase db = DBHelper.getWritableDatabase();

db.beginTransaction();
try {
    String  str = "INSERT INTO DBAdapter.KEY_BD1_DB_NAME(a, b, c, d, e, f,g) VALUES(?, ?, ?, ?, ?, ?,?)";
    SQLiteStatement statement = db.compileStatement(str);

    statement.bindLong(1, id);
    statement.bindString(4, strTStamp[0]);
    statement.bindString(5, strTStamp[1]);
    statement.bindLong(6, j);
    statement.bindLong(7, tstamp);

    for (int i=0;i<arraylist.length;i  ) {
            statement.bindLong(2, alist[i]);
            statement.bindLong(3, blist[i]);
            statement.executeInsert();
    }

    db.setTransactionSuccessful();
    Log.d("INSERT","Done");
    return true;
} catch (SQLException ex) {
    Log.w("SqlErr", "At kkr : "   ex.toString());
    return false;
} finally {
    db.endTransaction();
    db.close();
}
  

Другие материалы:

  • Синхронная ПРАГМА = ВЫКЛ может быть быстрее, но это сопряжено с рисками.
  • Стандартный трюк с массовой вставкой заключается в удалении любых индексов в таблице, вставке данных, а затем последующем повторном создании индексов.
  • При использовании внешних ключей временное отключение их принудительного выполнения во время массовой вставки также может ускорить процесс. Просто не забудьте позже поискать проблемы с PRAGMA foreign_key_check.

Комментарии:

1. Большое тебе спасибо, Шон

Ответ №2:

Похоже, вы пытаетесь заполнить базу данных при первом использовании. Но вместо этого было бы намного лучше, быстрее и проще просто отправить ваше приложение с готовым к использованию файлом базы данных в assets/ вашем приложении, а затем при первом использовании просто использовать эту базу данных для «заполнения» вместо этого. Есть несколько вспомогательных библиотек, которые помогают в этом:https://github.com/jgilfelt/android-sqlite-asset-helper