Массовая вставка на устройство Android

49

Я хочу, чтобы вставлять около 700 записей в базу Android для моего следующего обновления. Какой самый эффективный способ сделать это? Из разных сообщений я знаю, что если я использую операторы Insert, я должен обернуть их в транзакцию. Там также сообщение об использовании вашей собственной базы данных, но мне нужны эти данные, чтобы перейти в стандартную базу данных Android для Android. Обратите внимание, что это будет сделано только один раз для каждого устройства.

Некоторые идеи:

  • Поместите кучу операторов SQL в файл, прочитайте их в строке за раз и выполните SQL.

  • Поместите данные в файл CSV, или JSON, или YAML, или XML, или что-то еще. Прочитайте строку за раз и сделайте db.insert().

  • Выясните, как сделать импорт и выполнить единый импорт всего файла.

  • Создайте базу данных sqlite, содержащую все записи, скопируйте ее на Android-устройство и каким-то образом объедините две базы данных.

  • [EDIT] Поместите все операторы SQL в один файл в res/values ​​как одну большую строку. Затем прочитайте их строку за раз и выполните SQL.

Какой лучший способ? Существуют ли другие способы загрузки данных? Возможны ли 3 и 4?

Теги:
bulkinsert

5 ответов

8
Лучший ответ

Я не верю, что есть возможный способ выполнить # 3 или # 4 в вашем списке.

Из других решений вы перечислите два, у которых файл данных содержит прямой SQL, а другой - данные в формате, отличном от SQL.

Все три будут работать отлично, но последнее предложение захватить данные из форматированного файла и построения SQL файла кажется самым чистым. Если новая возможность пакетного обновления добавлена ​​позднее, ваш файл данных по-прежнему можно использовать или, по крайней мере, легко перерабатывать в пригодную для использования форму. Кроме того, создание файла данных является более простым и менее подверженным ошибкам. Наконец, наличие "сырых" данных позволит импортировать в другие форматы хранения данных.

В любом случае вы должны (как вы упомянули) обернуть группы вставок в транзакции, чтобы избежать создания журнала транзакций каждой строки.

93

Обычно каждый раз, когда используется db.insert(), SQLite создает транзакцию (и результирующий файл журнала в файловой системе), что замедляет работу.

Если вы используете db.beginTransaction() и db.endTransaction(), SQLite создает только один файл журнала в файловой системе, а затем фиксирует все вставки одновременно, значительно ускоряя работу.

Вот несколько псевдокодов: Пакетная вставка в базу данных SQLite на Android

try
{
  db.beginTransaction();

  for each record in the list
  {
    do_some_processing();

    if (line represent a valid entry)
    {
      db.insert(SOME_TABLE, null, SOME_VALUE);
    }

    some_other_processing();
  }

  db.setTransactionSuccessful();
}
catch (SQLException e) {}
finally
{
  db.endTransaction();
}

Если вы хотите прервать транзакцию из-за неожиданной ошибки или чего-то еще, просто db.endTransaction() без предварительной настройки транзакции (db.setTransactionSuccessful()).

Другим полезным методом является использование db.inTransaction() (возвращает true или false), чтобы определить, находитесь ли вы в настоящий момент в середине транзакции.

Документация здесь

  • 0
    после этого база данных заблокирована, как ее разблокировать ..
  • 2
    Для получения дополнительной ссылки на код: Пакетная вставка в базу данных SQLite на Android
Показать ещё 7 комментариев
33

Я обнаружил, что для массовых вставок класс (явно малоиспользуемый) DatabaseUtils.InsertHelper в несколько раз быстрее, чем при использовании SQLiteDatabase.insert.

Две другие оптимизации также помогли мне в производительности моего приложения, хотя они могут быть неприемлемы во всех случаях:

  • Не bind значения, которые пусты или null.
  • Если вы можете быть определенным безопасным для этого, временное отключение внутренней блокировки базы данных также может помочь в производительности.

У меня есть сообщение в блоге с более подробной информацией.

  • 0
    Спасибо! Эта оптимизация увеличила импорт группы записей в 2 раза.
  • 0
    Я читаю блог и комментарии. Обе предоставленные детали достаточно, чтобы вставить все мои данные за пару секунд. Много раз лучше, чем несколько минут.
Показать ещё 4 комментария
9

Этот пример ниже будет отлично работать

 String sql = "INSERT INTO " + DatabaseHelper.TABLE_PRODUCT_LIST
                + " VALUES (?,?,?,?,?,?,?,?,?);";

        SQLiteDatabase db = this.getWritableDatabase();
        SQLiteStatement statement = db.compileStatement(sql);
        db.beginTransaction();
        for(int idx=0; idx < Produc_List.size(); idx++) {
            statement.clearBindings();
            statement.bindLong(1, Produc_List.get(idx).getProduct_id());
            statement.bindLong(2,  Produc_List.get(idx).getCategory_id());
            statement.bindString(3, Produc_List.get(idx).getName());
//            statement.bindString(4, Produc_List.get(idx).getBrand());
            statement.bindString(5, Produc_List.get(idx).getPrice());
            //statement.bindString(6, Produc_List.get(idx).getDiscPrice());
            statement.bindString(7, Produc_List.get(idx).getImage());
            statement.bindLong(8, Produc_List.get(idx).getLanguage_id());
            statement.bindLong(9, Produc_List.get(idx).getPl_rank());
            statement.execute();

        }
        db.setTransactionSuccessful();
        db.endTransaction();
9

Ну, мое решение для этого это странно, но отлично работает... Я собираю большую сумму данных и вставляю их за один раз (объемная вставка?)

Я использую команду db.execSQL(Query), и я строю "запрос" со следующим утверждением...

INSERT INTO yourtable SELECT * FROM (
    SELECT 'data1','data2'.... UNION
    SELECT 'data1','data2'.... UNION
    SELECT 'data1','data2'.... UNION
    .
    .
    .
    SELECT 'data1','data2'....
)

Единственная проблема - это создание запроса, который может быть беспорядочным. Я надеюсь, что это поможет

  • 0
    Здорово. Какое отличное творческое решение. Похоже, это будет довольно быстро. Это?
  • 1
    Это было бы так быстро с классом StringBuilder.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню