Не вдаваясь в подробности, у меня в приложении для iOS есть процесс, который анализирует XML и вставляет (иногда до 10 или 100 с) тысячи записей в таблицу Sqlite3.
Для ускорения у меня нет индексов в таблице, и я сначала вставляю записи во временную таблицу в памяти, а затем перемещаю их в финальную таблицу партиями по 400. Ни во временной таблице, ни в таблице файловой системы нет индексов. .
Проблема, которую я замечаю, состоит в том, что в начале процесса требуется около 10-й секунды, чтобы сбросить 400 записей на диск. Затем с каждым сбросом это занимает все больше и больше времени, а через минуту или две требуется 3 секунды, чтобы сбросить 400 записей. Чем дольше, тем дольше. Каждый сброс занимает примерно на 1–2 десятых секунды дольше, чем предыдущий.
Поскольку я не использую никаких индексов, кто-нибудь может объяснить, почему это происходит, и порекомендовать решение?
Обновление 1:
Я попытался установить PRAGMA syncronous = OFF;
, и хотя это немного ускорило процесс, оно все равно стало на долю секунды медленнее с каждым INSERT SELECT
до точки, где оно будет кратно секундам для каждого сброса после нескольких тысяч строк. Я продолжу пробовать другие оптимизации, чтобы посмотреть, смогу ли я добраться до сути этого ...
Обновление 2:
Разъяснение того, что я делаю: я вставляю записи, когда они анализируются, во временную таблицу, которая находится в памяти, до тех пор, пока счетчик не достигнет 400, как подсчитывается с помощью int в коде Objective-C. Как только количество записей равно 400, я делаю один INSERT SELECT, чтобы переместить строки в таблицу на диске, затем я делаю DELETE * из таблицы памяти. Я рассчитываю каждую часть. Sqlite3 оптимизирует DELETE *, когда у него нет предложения WHERE, так что это похоже на удаление и повторное создание таблицы, и это очень быстро, менее чем за сотую долю секунды. Это только INSERT SELECT из таблицы памяти в таблицу дисков, скорость которой уменьшается каждый раз. Этот запрос начинается примерно с 0,1 секунды, и после каждой вставки пакета из 400 записей на запрос уходит примерно от 0,1 до 0,2 секунды дольше, чем до последнего, пока в итоге не потребуется несколько секунд, чтобы переместить 400 строк из памяти в диск каждый раз.
Обновление 3: Вот мои операторы создания таблиц и оператор, который я использую для перемещения записей из памяти на диск. Там нет ключей вообще. И да, мой sqlite настроен так, что временная таблица находится в памяти, а не на диске.
Временная таблица в памяти:
CREATE TEMPORARY TABLE allSongsTemp (title TEXT, songId TEXT, artist TEXT, album TEXT, genre TEXT, coverArtId TEXT, path TEXT, suffix TEXT, transcodedSuffix TEXT, duration INTEGER, bitRate INTEGER, track INTEGER, year INTEGER, size INTEGER);
Таблица на диске:
CREATE TABLE allSongsUnsorted (title TEXT, songId TEXT, artist TEXT, album TEXT, genre TEXT, coverArtId TEXT, path TEXT, suffix TEXT, transcodedSuffix TEXT, duration INTEGER, bitRate INTEGER, track INTEGER, year INTEGER, size INTEGER);
Запросы на сброс записей памяти на диск:
INSERT INTO allSongsUnsorted SELECT * FROM allSongsTemp;
DELETE * FROM allSongsTemp;
Запрос, который каждый раз занимает все больше и больше времени, равен # 3, INSERT SELECT
. DELETE
занимает около 1/100 секунды каждый раз.