Вверх ↑
Ответов: 321
Рейтинг: 10
#1: 2018-12-28 18:41:30 ЛС | профиль | цитата
Привет форум, привет ребята.
Подскажите, может кто сталкивался с проблемой - медленной скоростью добавления данных в бд ?!
Выборка из 9000 строк занимает на i7-8700k 11 секунд, с учетом, что 3200 mhz оперативка с хорошими таймингами и m2 ssd накопитель.

Цитата с https://www.sqlite.org/faq.html#q19

(19) INSERT is really slow - I can only do few dozen INSERTs per second

Actually, SQLite will easily do 50,000 or more INSERT statements per second on an average desktop computer. But it will only do a few dozen transactions per second. Transaction speed is limited by the rotational speed of your disk drive. A transaction normally requires two complete rotations of the disk platter, which on a 7200RPM disk drive limits you to about 60 transactions per second.
Transaction speed is limited by disk drive speed because (by default) SQLite actually waits until the data really is safely stored on the disk surface before the transaction is complete. That way, if you suddenly lose power or if your OS crashes, your data is still safe. For details, read about atomic commit in SQLite..

By default, each INSERT statement is its own transaction. But if you surround multiple INSERT statements with BEGIN...COMMIT then all the inserts are grouped into a single transaction. The time needed to commit the transaction is amortized over all the enclosed insert statements and so the time per insert statement is greatly reduced.

Another option is to run PRAGMA synchronous=OFF. This command will cause SQLite to not wait on data to reach the disk surface, which will make write operations appear to be much faster. But if you lose power in the middle of a transaction, your database file might go corrupt.

PRAGMA synchronous=OFF это что такое ?! Его выключить нужно или я лезу совсем не туда, у нас такого вообще наверное нету ?!

Цитата с https://habr.com/post/149356/

А почему все жалуются, что SQLite — тормозит?

Две причины. Первая — настройки по умолчанию. Они работают на надежность, а не на производительность.
Вторая — непонимание механизма фиксации транзакций. По умолчанию после любой команды SQlite будет фиксировать транзакцию (то есть ожидать пока БД окажется в целостном состоянии для отключения питания). В зависимости от режима паранойи SQLite потратит на это от 50 до 300 мс (ожидая окончания записи данных на диск).

Что делать-то? Мне нужно вставить 100 тыс записей и быстро!

Удалить индексы, включить режим синхронизации OFF (или NORMAL), вставлять порциями по N тысяч (N — подобрать, для начала взять 5000). Перед вставкой порции сделать BEGIN TRANSACTION, после — COMMIT.

Схема:

Add(MainForm,14842589,357,329)
{
Left=20
Top=105
Width=876
Height=496
Caption="SQLite_with_SQLiteDataSource"
Position=1
}
Add(DS_SQLite,10857796,490,343)
{
Name="db"
link(onOpen,12881291:doExec,[])
}
Add(DSC_Query,11075216,882,434)
{
SQL="SELECT color,mid ,loc ,obj ,x ,y ,z FROM "db";"
DSManager="db"
link(onQuery,15928964:doAddRow,[])
}
Add(MST_DB,15928964,931,434)
{
MSTControl="mtst"
}
Add(DSC_Exec,12881291,546,343)
{
@Hint=#19:Создание таблицы БД|
SQL="CREATE TABLE db (\r\ncolor int NULL,\r\nid TEXT NULL,\r\nmid int(3) NULL,\r\nloc TEXT NULL,\r\nobj TEXT NULL,\r\nx TEXT NULL,\r\ny TEXT NULL,\r\nz TEXT NULL);\r\n"
DSManager="db"
link(onExec,15116110:doStart,[])
AddHint(36,-34,129,13,@Hint)
}
Add(HTTPClient,6804313,658,343)
{
URL="ff.zzz.com.ua/load2.php"
Method=1
EncType=1
PostData="k=1000\r\nrealm=WoW Circle x1 PvE Virgin "
Point(PostData)
link(onFinish,2930276:doCharset,[])
}
Add(Charset,2930276,714,350)
{
Type=7
link(onCharset,3200969:doEnum,[])
}
Add(FormatStr,2243243,840,350)
{
DataCount=1
Mask="INSERT INTO "db" VALUES(%1);"
link(onFString,9164852:doExec,[])
}
Add(Str_Enum,3200969,770,350)
{
Delimiter="_"
From=0
link(onEnum,2243243:doString,[])
link(onEndEnum,14968106:doEvent1,[(824,363)(824,440)])
}
Add(DSC_Exec,9164852,889,350)
{
DSManager="db"
}
Add(Button,4618125,357,371)
{
Left=70
Top=230
Caption="Load"
link(onClick,9796737:doStart,[(401,377)(401,349)])
}
Add(Thread,15116110,602,343)
{
Delay=0
FastStop=0
link(onExec,6804313:doLoadString,[])
}
Add(Message,10730767,357,413)
{
}
Add(Hub,14968106,847,434)
{
link(onEvent1,11075216:doQuery,[])
link(onEvent2,9796737:doStop,[(876,447)(876,476)(415,476)(415,356)])
}
Add(TimeCounter,9796737,427,343)
{
link(onStart,10857796:doOpen,[])
link(onStop,8113786:doEvent1,[(471,356)(471,315)(224,315)(224,335)])
}
Add(Hub,8113786,245,329)
{
link(onEvent1,14842589:doCaption,[])
link(onEvent2,13152047:doStrCat,[(277,342)(277,419)])
}
Add(StrCat,13152047,287,413)
{
Str1="Добавлено строк - "
link(onStrCat,10730767:doMessage,[])
link(Str2,3870454:Count,[])
}
Add(MTStrTbl,3870454,280,357)
{
Width=860
Height=183
Align=2
Name="mtst"
Layout="vert_1"
HeightScale=100
Columns=#8:MapID_50|11:Локация_120|10:Объект_120|4:X_80|4:Y_80|4:Z_80|
NColorRow=0
FlatScroll=1
ColDelimiter="_"
ColumnClick=1
ColorItems=0
}


Причем рассуждал так, думал что медленно из-за того, что 9к запросов, по одной строке якобы ему сложно добавлять, потом сделал сначала запись в strList и думал одним sql запросом добавить все, но получилось добавляет 3700 чтоли... ну видимо есть ограничения на длину запроса за раз, либо он прерывает выполнение из-за моих ошибок, просто в некоторых строках у меня символ ' , не знаю как с ним бороться... короче таким способом скорость осталась такая же, так еще стал меньше добавлять данных в таблицу...

Вторичная проблема - это то, что я не могу сделать выборку строк по фразе, типа where obj=бла бла, то есть, где есть пробел, с одним словом все хорошо.
карма: 1

0