sqlite3_exec с явной транзакцией и без нее - PullRequest
0 голосов
/ 25 сентября 2019

С помощью следующего кода:

sqlite3_exec(db, "BEGIN TRANSACTION", NULL, NULL, NULL);
for (int i=0; (row=rows[i]).id != NULL; i ++) {
    if (i == 100000) break;
    asprintf(&query, "insert into Sales1M (id, date, instance_id, territory_id, code, price, currency_code_id, price_in_usd)"
                     "values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s');",
                      row.id, row.date, row.instance_id, row.territory_id, row.code, row.price, row.currency_code_id, row.price_in_usd);
    rc = sqlite3_exec(db, query, NULL, NULL, &error_msg);
}
sqlite3_exec(db, "COMMIT TRANSACTION", NULL, NULL, NULL);

InsertSQL: 0.384135s для выполнения вставки 100K.

Однако, если я удаляю BEGIN TRANSACTION...,вставки почти в 100 раз медленнее:

InsertSQL: 4.592789 для выполнения вставок 100K.

Почему это так?

Автоматически ли SQLite выполняет BEGIN...COMMIT как оболочка для команды sqlite3_exec, если ожидающий TRANSACTION еще не установлен?Или, почему это занимает так много времени без явного начала / принятия в транзакции?

1 Ответ

1 голос
/ 25 сентября 2019

Потому что, если вы не сделаете BEGIN...COMMIT, то после каждого оператора будет неявный один (COMMIT - это однострочная строка, которая возвращает его к фиксации в конце оператора).

После того, какСделав это, вы ограничены временем записи на диск, которое составит 10 секунд миллисекунд на строку (меньше, если SSD, но все же намного больше, чем это можно сделать, если не выполнять фиксацию после каждой строки).Вы не хотите этого.

Пакетные вставки.В настоящее время для типичного оборудования пишется около 10 000 строк на транзакцию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...