Что нового

SQLite Очень медленное добавление записей в таблицу

pvnn

Осваивающий
Сообщения
305
Репутация
32
Всем доброго времени суток!
Заполнение текстового файла в 1000 строк занимает времени меньше секунды.
Заполнение же таблицы SQLite происходит в 100 раз медленнее (50-60 сек).
Это нормальная скорость для Autoit или можно как-то оптимизировать?
Вообще, хотелось бы обработать около 50-70 тыс. строк максимум.

Пример скрипта:
Код:
#include <Date.au3>

 #include <SQLite.au3>
 #include <SQLite.dll.au3>

_SQLite_Startup()
If @error Then
    MsgBox(16, "Ошибка SQLite", "Не удалось загрузить SQLite.dll")
    Exit -1
EndIf


; Запись в TXT
$StartDateTime= _NowCalc()
$hFile=FileOpen(@ScriptDir&'\test.txt',2)
For $i=1 To 1000
	FileWriteLine($hFile,$i)
Next
FileClose($hFile)
; Время работы
$EndDateTime= _NowCalc()
$TimeWork=_DateDiff("s", $StartDateTime, $EndDateTime)
MsgBox(64,'Длительность (сек)',$TimeWork)


; Запись в SQLite данных из TXT-файла
$StartDateTime= _NowCalc()
$SQLite_Data_Path=@ScriptDir&'\test.db'
; Создать Базу данных
	If FileExists($SQLite_Data_Path) Then FileDelete($SQLite_Data_Path) ; Удалить Базу данных, если она существует

	_SQLite_Open($SQLite_Data_Path) ; Создать БД
	If @error Then
		MsgBox(16, "Ошибка SQLite", "Не удалось создать базу данных")
	EndIf
	 ; Создать таблицу tList
	_SQLite_Exec(-1, "Create Table IF NOT Exists tList (ID INTEGER PRIMARY KEY AUTOINCREMENT, Num Text);")
	_SQLite_Close()

$hFile=FileOpen(@ScriptDir&'\test.txt')
While 1
	$line = FileReadLine($hFile)	; Считываем строку из файла
	IF @error = -1 Then ExitLoop
	; Запись данных в таблицу
	_SQLite_Open($SQLite_Data_Path)
	_SQLite_Exec(-1, "Insert into tList (Num) values ('"&$line&"');")
	_SQLite_Close()
WEnd
; Время работы
$EndDateTime= _NowCalc()
$TimeWork=_DateDiff("s", $StartDateTime, $EndDateTime)
MsgBox(64,'Длительность (сек)',$TimeWork)

Exit
 

alex33

Скриптер
Сообщения
1,457
Репутация
186
pvnn, Да, у меня такая же проблема, тоже очень медленно. :smile:
Запустил, сижу жду и вдруг выдал 101 при добавление в базу, а в файл вон за 0 секунд добавляет...
P.S. Я только там это всё на TimerInit/Diff заменил...
OffTopic:
Правильно я делал, что раньше только на файлах сидел и баз данных не воспринимал...
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
pvnn [?]
Заполнение же таблицы SQLite происходит в 100 раз медленнее (50-60 сек).
Это нормальная скорость для Autoit или можно как-то оптимизировать?
Давайте попробуем. :smile:
Код:
#include <SQLite.au3>
;~  #include <SQLite.dll.au3>

Global $sFileDB = @ScriptDir & '\test.db', $hDB, $iTimer, $sExec

_SQLite_Startup()

;~ 1. очень долго (как у Вас)
$iTimer = TimerInit()
$hDB = _SQLite_Open($sFileDB)
_SQLite_Exec($hDB, 'DROP TABLE IF EXISTS TEST;CREATE TABLE TEST([NUM_TEST] INTEGER);')
_SQLite_Close($hDB)
For $i = 1 To 10000
	$hDB = _SQLite_Open($sFileDB)
	_SQLite_Exec($hDB, 'INSERT INTO TEST VALUES (' & $i & ');')
	_SQLite_Close($hDB)
Next
ConsoleWrite(StringFormat('1.\t%.2f sec\n', TimerDiff($iTimer) / 1000))

;~ 2. просто долго
$iTimer = TimerInit()
$hDB = _SQLite_Open($sFileDB)
_SQLite_Exec($hDB, 'DROP TABLE IF EXISTS TEST;CREATE TABLE TEST([NUM_TEST] INTEGER);')
For $i = 1 To 10000
	_SQLite_Exec($hDB, 'INSERT INTO TEST VALUES (' & $i & ');')
Next
_SQLite_Close($hDB)
ConsoleWrite(StringFormat('2.\t%.2f sec\n', TimerDiff($iTimer) / 1000))

;~ 3. быстро
$iTimer = TimerInit()
$hDB = _SQLite_Open($sFileDB)
_SQLite_Exec($hDB, 'BEGIN;DROP TABLE IF EXISTS TEST;CREATE TABLE TEST([NUM_TEST] INTEGER);')
For $i = 1 To 10000
	_SQLite_Exec($hDB, 'INSERT INTO TEST VALUES (' & $i & ');')
Next
_SQLite_Exec($hDB, 'COMMIT;')
_SQLite_Close($hDB)
ConsoleWrite(StringFormat('3.\t%.2f sec\n', TimerDiff($iTimer) / 1000))

;~ 4. еще быстрее
$iTimer = TimerInit()
$sExec = 'BEGIN;DROP TABLE IF EXISTS TEST;CREATE TABLE TEST([NUM_TEST] INTEGER);'
For $i = 1 To 10000
	$sExec &= 'INSERT INTO TEST VALUES (' & $i & ');'
Next
$sExec &= 'COMMIT;'
$hDB = _SQLite_Open($sFileDB)
_SQLite_Exec($hDB, $sExec)
_SQLite_Close($hDB)
ConsoleWrite(StringFormat('4.\t%.2f sec\n', TimerDiff($iTimer) / 1000))

_SQLite_Shutdown()
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
OffTopic:
pvnn [?]
Заполнение текстового файла в 1000 строк занимает времени меньше секунды.
Разгон Bugatti Veyron 0—100 км/ч = 2,5 с
Заполнение же таблицы SQLite происходит в 100 раз медленнее (50-60 сек).
Разгон Bugatti Galibier 16c 0—100 км/ч занимает 3 с.
Это нормальная скорость для Autoit или можно как-то оптимизировать?
Это нормально для Bugatti Automobiles?

Как-то так примерно звучит ваш вопрос :smile:
Опишите ситуацию подробнее, прикрепите текстовый файл и т.д. ит.п.
 

alex33

Скриптер
Сообщения
1,457
Репутация
186
Код:
;~ 1. очень долго (как у Вас)
Вот уже 5 минут (если не больше) прошло и он всё с первым справиться не может...
А кстати: с чем это связано и из-за чего так происходит? Почему он "зависает"?
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
alex33 [?]
Вот уже 5 минут (если не больше) прошло и он всё с первым справиться не может...
Замените 10000 на 1000. У меня в консоли с 10000:
Код:
1.	112.18 sec
2.	94.32 sec
3.	2.01 sec
4.	0.13 sec
с чем это связано и из-за чего так происходит? Почему он "зависает"?
Я Вам дал четыре примера. Читайте их внимательно и найдите отличия.
 

alex33

Скриптер
Сообщения
1,457
Репутация
186
А я так и оставил 10000 (для эксперемента) и у меня
1. 1042.97 sec
Ну это я чуть не офигел :D :D :smile: :( :smile:

3. 1.66 sec
4. 0.26 sec
Ну вот это уже круто... :smile:
 
Автор
P

pvnn

Осваивающий
Сообщения
305
Репутация
32
madmasles Спасибо за отличные примеры. Это как раз то, что нужно!
Очень выручили!
Тема решена
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
pvnn, alex33
Вероятно, причина в этом
Если вы не используете транзакции явно (BEGIN; …; COMMIT;), то всегда создается неявная транзакция. Она стартует перед выполнением команды и коммитится сразу после.
Отсюда, кстати, и жалобы на «медленность» SQLite. SQLite может вставлять и до 50 тыс записей в секунду, но фиксировать транзакций он не может больше, чем ~ 50 в секунду.
Именно поэтому, не получается вставлять записи быстро, используя неявную транзакцию.
http://www.pvsm.ru/razrabotka/13194
 

sims

Осваивающий
Сообщения
184
Репутация
24
InnI [?]
SQLite может вставлять и до 50 тыс записей в секунду
На практике это подтвердилось.
Вариант номер 3, производит примерно 90 тысяч записей в секунду.
 
Верх