Вопросы | sqlite

SQLite неисключительная зарезервированная блокировка?

Вопрос

Kyle Cronin | 1254 просмотров | рейтинг: 1

Я искал улучшения производительности SQLite для своего сайта, особенно в отношении транзакций. По сути, я ищу способ отложить запись в базу данных в процессе, чтобы все они могли быть выполнены одновременно. Тем не менее, пока я накапливаю запросы на обновление, я бы хотел, чтобы другие процессы могли выполнять чтение и запись в базу данных и блокировать файл для записи только после того, как в процессе выдается коммит. При просмотре документации кажется, что, как только в транзакции введена команда обновления, процесс получает зарезервированную блокировку, что (если я правильно помню) означает, что любой другой процесс, который пытается добавить запрос на обновление в свою собственную транзакцию или зафиксировать транзакцию не удается, и поэтому блокируется, пока транзакция не фиксируется в процессе с блокировкой. Я уверен, что есть очень хорошие причины целостности данных против этой конкретной функции. Все, что я могу сказать, это то, что в моем случае нет опасности одновременно выполнять эти обновления. Одним из решений является то, что в каждом процессе я мог бы накапливать текст запросов, которые я хочу вызвать, в массиве, а затем зацикливать его, как только я буду готов к записи, но мне интересно, возможно ли выполнить транзакцию SQLite для сделай это для меня автоматически. update: Я имею в виду, что когда я делаю все свои обновления одновременно, я использую транзакции в SQLite, чтобы получить только ИСКЛЮЧИТЕЛЬНУЮ блокировку и запись на диск один раз для каждого процесса, а не один раз для запроса. Это приводит к ускорению в 100 раз с использованием SQLite. Я провел некоторое базовое тестирование, и кажется, что если у вас есть несколько процессов, добавляющих запросы к своим транзакциям, когда вы нажимаете запрос на обновление, этот процесс пытается получить зарезервированную блокировку. Поскольку только один процесс может иметь зарезервированную блокировку, это означает, что любые другие процессы, пытающиеся получить блокировку, будут блокироваться, пока процесс с блокировкой не завершит транзакцию. Я признаю, что эта проблема может быть преждевременной оптимизацией, поскольку мне еще не приходилось сталкиваться с какими-либо штрафами за производительность, но я провел несколько простых тестов, и 100 пользователей, каждый из которых для создания и запуска транзакции со 100 запросами, занимает около 4 секунд в PHP на моем компьютере.



Ответы

Doug Currie

+ 3 -
SQLite поддерживает ATTACH для подключения одной базы данных к другой. Возможно, вы можете накапливать свои данные в отдельной базе данных, и когда вы будете готовы объединить накопленные строки, присоедините отдельную базу данных, скопируйте строки в одном выражении и отсоедините. Редактировать: аналогичное предложение было сделано в ветке списка рассылки на sqlite-users с последующим обсуждением.  


UrOni

+ 1 -
Лучше, чем прикрепить базу данных, просто создать временную таблицу. (СОЗДАТЬ ВРЕМЕННОЕ ...) И взгляните на новый режим журнала WAL, который точно выполняет то, что вы пытаетесь сделать вручную, и позволяет одновременную запись и чтение (хотя не одновременную запись). #pragma journal_mode = WAL


Теги

sqlite | concurrency | locking | reserved