У меня есть таблица ресурсов с 2000 строк. Двигатель innodb. Есть поле 'free_at' (индексированное). По каждому запросу мне нужно заблокировать таблицу, получить бесплатный ресурс (упорядоченный по столбцу «free_at»), обновить эту строку до несвободной и снять блокировку.
Это базовая реализация пула, которую я использовал, и она отлично работала со 100-200 подключениями и менее чем 1000 строк (ресурсы в пуле).
Сейчас около 800 процессов, которые постоянно запрашивают ресурсы из таблицы (каждый раз в 10-15 секунд, то есть в среднем до 80\с).
Моим узким местом является время ожидания блокировки, которое составляет от 30 до 60 секунд (!) для каждого запроса. Я уверен, что есть какая-то конфигурация, которую я должен изменить, чтобы ускорить блокировку и освобождение.
Я попытался изменить тип двигателя на ПАМЯТЬ, но это не улучшило время ожидания блокировки.
Должен ли я искать другое решение для пула, которое не основано на MySQL и может распределять ресурсы по приоритету (в моем случае это поле «free_at»)?
РЕДАКТИРОВАТЬ:
для блокировки я использую LOCK TABLES table_name WRITE
Затем выберите SELECT * FROM table_name WHERE (free_at < NOW() OR free_at is null) ORDER BY free_at ASC
Обновление поля «free_at» UPDATE table_name SET free_at = NOW() + INTERVAL 5 MINUTE WHERE id= 1234
Наконец разблокировка UNLOCK TABLES
Схема таблицы
`resources` ( `id` int(11) NOT NULL AUTO_INCREMENT, `free_at` datetime DEFAULT NULL, PRIMARY KEY (`id`), KEY `free_at` (`free_at`), ) ENGINE=InnoDB
SELECT ... FOR UPDATE
? - person O. Jones   schedule 27.01.2014free_at IS NULL
окончательно исключает использование индекса в вашем выраженииSELECT
. - person O. Jones   schedule 28.01.2014