powered by simpleCommunicator - 2.0.40     © 2025 Programmizd 02
Форумы / Android [игнор отключен] [закрыт для гостей] / AsyncTask SQLite
16 сообщений из 16, страница 1 из 1
AsyncTask SQLite
    #38930579
Фотография НикоДимиден
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте! У меня в приложении есть БД SQLite, при нажатие на кнопку загрузки, приложение начинает в базу вносить записи.
Структура базы :
1.таблица-одна, колонка - одна
2.Кол-во записей : 20 000
3.Формат записи: String до 10 символов.

Метод добавления : через бэкграунд, фоновый поток, используя наследования класса "AsyncTask"


Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
class MyTask extends AsyncTask<Void, Integer, Void> {
	
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			Info.setText("Начали ");
		}

		@Override
		protected Void doInBackground(Void... params) {
			int counter = 0;
			try {			
				for(int i=0; i<20000;i++){		
		                        getFloor(counter);
					publishProgress(++counter);
			     	}	
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			return null;
		}

		@Override
		protected void onProgressUpdate(Integer... values) {
			super.onProgressUpdate(values);
			Info.setText("Позиция : " + values[0]);
			horizontalprogress.setProgress(values[0]);
		}
		
		@Override
		protected void onPostExecute(Void result) {
			super.onPostExecute(result);
			Info.setText("Загрузили");	
		}
		
		
		private void getFloor(int floor) throws InterruptedException {
	           // Метод 1: INSERT через класс CONTENTVALUE
                   ContentValues cv = new ContentValues();
                   cv.put("time", "Hello "+floor);
                  // вызываем метод вставки
                  Asqdb1.insert("alarm_table",null, cv);
		}
		
		
	}



При занесения записей в базу, уходит около 10-20 минут. Подскажите пожалуйста, нормальная ли это ситуация, когда так долго происходит добавления записей в БД?
Я понимаю что в фоновом потоке задачи выполняются медленнее. Но всё таки, мне кажется что то слишком долго.
...
Рейтинг: 0 / 0
AsyncTask SQLite
    #38930596
chpasha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
не нормально.
1) стартовать транзакцию до начала вставки, коммитить либо совсем в конце, либо каждые несколько тысяч записей (в конце или нет, зависит от задачи - т.е. устраивает, что вставится 4000 записей а потом по ошибке отвалится или нет)
2) используй InsertHelper или SQLiteStatement
...
Рейтинг: 0 / 0
AsyncTask SQLite
    #38930597
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вставлять нужно порциями...
Перед началом вставки порции явно открой транзакцию и затем явно закрой. Порции подбираются опытным путем. Я обычно делаю 1000. Проблема в том, что без этого транзакции стартуют и заканчиваются на каждый чих (вставку).

Ну и вставлять лучше через SQLiteStatement , а не через ContentValues.
...
Рейтинг: 0 / 0
AsyncTask SQLite
    #38930600
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chpashaне нормально.
1) стартовать транзакцию до начала вставки, коммитить либо совсем в конце, либо каждые несколько тысяч записей (в конце или нет, зависит от задачи - т.е. устраивает, что вставится 4000 записей а потом по ошибке отвалится или нет)
2) используй InsertHelper или SQLiteStatement
Хм...
...
Рейтинг: 0 / 0
AsyncTask SQLite
    #38930614
chpasha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadmanХм... это называется на кнопке обошел :)
...
Рейтинг: 0 / 0
AsyncTask SQLite
    #38930764
Микола Питерский
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Использованием общей транзакции ты увеличишь скорость вставки раза в 2.
Кури PRAGMA synchronous = 0 | OFF | 1 | NORMAL | 2 | FULL;
Этот сервак по умолчанию стоит в FULL - т.е. записывает КАЖДОЕ изменение на диск без кэширования, что и тормозит загрузку.
Перед массовой заливкой нужно передать PRAGMA synchronous OFF, после заливки "вернуть все на место". Вот тогда база SQLite летает - я когда-то грузил в нее несколько тысяч записей в секунду.
...
Рейтинг: 0 / 0
AsyncTask SQLite
    #38930848
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Микола ПитерскийВот тогда база SQLite летает - я когда-то грузил в нее несколько тысяч записей в секунду.
На средненьком смартфоне?
...
Рейтинг: 0 / 0
AsyncTask SQLite
    #38930856
Фотография НикоДимиден
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadman,

УХХХ!!Ты!!! Спасибо!
Скорость возросла в ДЕСЯТКИ РАЗ!!!! с 15-20 минут до 25 секунд!!!
Использовал транзактицию.
Еще сделаю метод добавления информации в базу данных, через SQLiteStatement, посмотрим насколько еще возрастет скорость.



Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
class MyTask extends AsyncTask<Void, Integer, Void> {
	
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			Info.setText("Начали ");
		}

		@Override
		protected Void doInBackground(Void... params) {
			int counter = 0;
                       //Открывает транзакцию
                       Asqdb1.beginTransaction();
			try {			
				for(int i=0; i<20000;i++){		
		                        getFloor(counter);
					publishProgress(++counter);
			     	}
                    	 //Одобряет транзакцию (Не знаю зачем это нужно (: )
                         Asqdb1.setTransactionSuccessful();
			} catch (InterruptedException e) {
				e.printStackTrace();
			} finally {
				//закрываем транзакцию
				Asqdb1.endTransaction();	
			}


			return null;
		}

		@Override
		protected void onProgressUpdate(Integer... values) {
			super.onProgressUpdate(values);
			Info.setText("Позиция : " + values[0]);
			horizontalprogress.setProgress(values[0]);
		}
		
		@Override
		protected void onPostExecute(Void result) {
			super.onPostExecute(result);
			Info.setText("Загрузили");	
		}
		
		
		private void getFloor(int floor) throws InterruptedException {
	           // Метод 1: INSERT через класс CONTENTVALUE
                   ContentValues cv = new ContentValues();
                   cv.put("time", "Hello "+floor);
                  // вызываем метод вставки
                  Asqdb1.insert("alarm_table",null, cv);
		}
		
		
	}
...
Рейтинг: 0 / 0
AsyncTask SQLite
    #38930869
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НикоДимиденУХХХ!!Ты!!! Спасибо!
А я-то что? chpasha был быстрее меня.
...
Рейтинг: 0 / 0
AsyncTask SQLite
    #38930888
Фотография НикоДимиден
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadman,
Да всем спасибо, кто откликнулся! :)
...
Рейтинг: 0 / 0
AsyncTask SQLite
    #38931180
Фотография НикоДимиден
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
С использованием класса SQLiteStatement, стало работать ещё быстрее почти в два раза. Вместо 24 секунд, 13 =)


Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
SQLiteStatement cv;
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

     //Инициализация
     cv = Asqdb1.compileStatement("INSERT INTO alarm_table (time) VALUES (?)");


}

class MyTask extends AsyncTask<Void, Integer, Void> {
	
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			Info.setText("Начали ");
		}

		@Override
		protected Void doInBackground(Void... params) {
			int counter = 0;
                       //Открывает транзакцию
                       Asqdb1.beginTransaction();
			try {			
				for(int i=0; i<20000;i++){		
		                        getFloor(counter);
					publishProgress(++counter);
			     	}
                    	 //Одобряет транзакцию (Не знаю зачем это нужно (: )
                         Asqdb1.setTransactionSuccessful();
			} catch (InterruptedException e) {
				e.printStackTrace();
			} finally {
				//закрываем транзакцию
				Asqdb1.endTransaction();	
			}


			return null;
		}

		@Override
		protected void onProgressUpdate(Integer... values) {
			super.onProgressUpdate(values);
			Info.setText("Позиция : " + values[0]);
			horizontalprogress.setProgress(values[0]);
		}
		
		@Override
		protected void onPostExecute(Void result) {
			super.onPostExecute(result);
			Info.setText("Загрузили");	
		}
		
		
		private void getFloor(int floor) throws InterruptedException {
	               cv.clearBindings();
			cv.bindString(1,"Hello "+String.valueOf(floor));
			cv.execute();
		}
		
		
	}
...
Рейтинг: 0 / 0
AsyncTask SQLite
    #38931202
Фотография НикоДимиден
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Микола Питерский,

Вы это делали?

SQLiteDatabase.execSQL(“PRAGMA synchronous=OFF”); Изменить способ записи в базу – без “синхронизации”. При выключении данной опции, база данных может быть повреждена при неожиданном сбое системы, либо отключении питания. Однако согласно документации SQLite некоторые операции при выключении данной опции выполняются более чем в 50 раз быстрее.

Это довольно опасно, как по мне.
...
Рейтинг: 0 / 0
AsyncTask SQLite
    #38931224
Фотография НикоДимиден
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По вашим рекомендациям я разделил добавления информации на некие ячейки, и теперь я добавляю не по одной записи а по 100.
Скорость выросла колоссально!!! Раньше загрузка длилась 15-20 минут, теперь 1,0 - 1,5 секунды. Я доволен)

пример:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
private void getFloor(int floor) throws InterruptedException {
	               cv.clearBindings();
			cv.bindString(1,"Hello "+String.valueOf(floor));
                        cv.bindString(1,"Hello "+String.valueOf(floor+1));
                        cv.bindString(1,"Hello "+String.valueOf(floor+2));
                        cv.bindString(1,"Hello "+String.valueOf(floor+3));
                        //..итд до 100

			cv.execute();
		}



Кстати на заметку. Я прочитал что можно еще воспользоваться NDK и написать код на с++. Тогда будет еще быстрее. Может кому понадобится.
...
Рейтинг: 0 / 0
AsyncTask SQLite
    #38931240
Фотография НикоДимиден
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А не..
7 секунд получилось.
Только я видимо как то не правильно добавляю записи


Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
                        cv.clearBindings();
			cv.bindString(1,"Hello "+String.valueOf(floor+1));
			cv.execute();

                        cv.clearBindings();
			cv.bindString(1,"Hello "+String.valueOf(floor+1));
			cv.execute();

                        cv.clearBindings();
			cv.bindString(1,"Hello "+String.valueOf(floor+1));
			cv.execute();
                     
                 // и так до 100

А вот так две записи не добавляются  :  
                        cv.clearBindings();
			cv.bindString(1,"Hello "+String.valueOf(floor+1));
                        cv.bindString(1,"Hello "+String.valueOf(floor+2));
			cv.execute();

так вылетает с ошибкой:
                        cv.clearBindings();
			cv.bindString(1,"Hello "+String.valueOf(floor+1));
                        cv.bindString(2,"Hello "+String.valueOf(floor+2));
			cv.execute();



Что я делаю не правильно?
...
Рейтинг: 0 / 0
AsyncTask SQLite
    #38931412
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НикоДимиден
Код: java
1.
2.
			cv.bindString(1,"Hello "+String.valueOf(floor+1));
                        cv.bindString(1,"Hello "+String.valueOf(floor+2));


Вторая строка замещает предыдущее значение.

НикоДимиден
Код: java
1.
так вылетает с ошибкой:


Наверняка у нее есть текст. Правда, я не заметил разницы между тем примером, что с ошибкой и тем, когда не добавляются две записи...
...
Рейтинг: 0 / 0
AsyncTask SQLite
    #38931427
Микола Питерский
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НикоДимиденМикола Питерский,

Вы это делали?

SQLiteDatabase.execSQL(“PRAGMA synchronous=OFF”); Изменить способ записи в базу – без “синхронизации”. При выключении данной опции, база данных может быть повреждена при неожиданном сбое системы, либо отключении питания. Однако согласно документации SQLite некоторые операции при выключении данной опции выполняются более чем в 50 раз быстрее.

Это довольно опасно, как по мне.

Ничего опасного - все сервера Кэшируют изменения в буффер и только потом записывают на диск этот буффер, а в SQLite буферизация отключена изначально.
...
Рейтинг: 0 / 0
16 сообщений из 16, страница 1 из 1
Форумы / Android [игнор отключен] [закрыт для гостей] / AsyncTask SQLite
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]