#android #java #sqlite
Здравствуйте! По совету из прошлого вопроса я не стал записывать нулевые ячейки в базу, теперь объём записываемых данных уменьшился с 25 165 824 до 6 881 280. Вопрос: можно ли ещё как-нибудь ускорить сохранение (сейчас оно занимает 140 секунд, хотелось бы сократить это время хотя бы до минуты) этих данных в базу? Вот мой код сохранения: void save() { final SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase(path, null); String sql_w_table = "CREATE TABLE w_data (" + "a LONG," + "b LONG," + "type LONG" + ");"; database.execSQL(sql_w_table); String query = "INSERT INTO w_data VALUES (?,?,?);"; SQLiteStatement st = database.compileStatement(query); database.beginTransaction(); for (int i = 0; i <= 32767; i++) { for (int n=0; n <= 255; n++) { int b = map[i][n]; if (b != 0) { st.bindLong(1, i); st.bindLong(2, n); st.bindLong(3, b); st.executeInsert(); st.clearBindings(); } } } database.setTransactionSuccessful(); database.endTransaction(); database.close(); }
Ответы
Ответ 1
Предлагаю самый наивный способ - не сохранять "поячеечно", а "построчно". Попробую на коленке переписать (!!). void save() { final SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase(path, null); String sql_w_table = "CREATE TABLE w_data (" + "a LONG," + "type TEXT" + ");"; database.execSQL(sql_w_table); String query = "INSERT INTO w_data VALUES (?,?);"; SQLiteStatement st = database.compileStatement(query); database.beginTransaction(); for (int i = 0; i <= 32767; i++) { String s = ''; for (int n=0; n <= 255; n++) { s += map[i][n] + " "; } st.bindLong(1, i); st.bindLong(2, s); st.executeInsert(); st.clearBindings(); } database.setTransactionSuccessful(); database.endTransaction(); database.close(); } суть - в базу сохраняем сразу по строке. Когда нужно будет распаковывать, то используем обычный метод split у строки. Можно пойти дальше и использовать blob и сохранять строку в один подход. Андроидовская обвязка для blob умеет сохранять массив byte. Класс java.nio.IntBuffer и java.nio.ByteBuffer позволяют завернуть массив int в массив byte. Вот пример как сохраняют картинку в базу. Но я верю, что сохранение в файл будет как минимум не медленнее (если только не сохранять поэлементно).Ответ 2
Одного не понимаю, зачем здесь нужны транзакции в локальной БД куда юзер/аппа имеет монопольный доступ? Ну я бы еще понял, если автор где-то при ошибке вставки откатывал бы транзакции и проч. - но этого ведь нет. Раз так, то напрашивается рецепт: для ускорения вставок я бы рекомендовал установить наинизший возможный уровень изоляции транзакций: PRAGMA read_uncommitted = 1; И убрал бы словеса beginTransaction/endTransaction и проч. ненужную в данном контексте муть Еще бы поигрался с местом хранения временных файлов: PRAGMA temp_store = 0 | DEFAULT | 1 | FILE | 2 | MEMORY;Ответ 3
Судя по коду, bulk insert вам поможет.Ответ 4
Попробуйте установить другой вариант синхронизации: PRAGMA synchronous = 0 | OFF | 1 | NORMAL | 2 | FULL; Но тут надо понимать что если вырубание питания, или ещё какой непредвиденный косяк у Вас может "умереть" база. Хотя PRAGMA synchronous = 0 скорость увеличится раз в 10сять. И попробуйте ещё закидывать не по одному инсерту а по "пачке".
Комментариев нет:
Отправить комментарий