Я создал приложение-службу, которое использует многопоточность для параллельной обработки данных, расположенных в таблице InnoDB (около 2-3 миллионов записей, и больше никаких запросов, связанных с InnoDB, выполняемых приложением).Каждый поток выполняет следующие запросы к упомянутой таблице:
- ЗАПУСК СДЕЛКИ
- ВЫБРАТЬ ДЛЯ ОБНОВЛЕНИЯ (ВЫБРАТЬ pk ИЗ таблицы, ГДЕ состояние = «новый» ПРЕДЕЛ 100 ДЛЯ ОБНОВЛЕНИЯ)
- ОБНОВЛЕНИЕ (ОБНОВЛЕНИЕ таблицы состояния SET = «заблокирован» ГДЕ ПК между X и Y)
- COMMIT
- УДАЛИТЬ (УДАЛИТЬ ИЗ таблицы, ГДЕ ПК между X и Y)
Ребята из forum.percona.com дали мне совет - не используйте SELECT FOR UPDATE и UPDATE из-за более длительного времени, необходимого для выполнения транзакции (2 запроса), и ожидаемых тайм-аутов блокировки.Их совет был (автокоммит включен):
- ОБНОВЛЕНИЕ (ОБНОВЛЕНИЕ таблицы SET, состояние = «заблокировано», поток = Z LIMIT 100)
- ВЫБРАТЬ (ВЫБРАТЬ pk ИЗ таблицы, ГДЕ поток =Z)
- УДАЛИТЬ (УДАЛИТЬ ИЗ ТАБЛИЦЫ ГДЕ pk МЕЖДУ X И Y)
, и это должно было улучшить производительность.Однако вместо этого я получил еще больше взаимоблокировок и тайм-аутов ожидания, чем раньше ...
Я много читал об оптимизации InnoDB и соответственно настроил сервер, так что мои настройки InnoDB на 99% в порядке.Этот факт также подтверждается тем, что первый сценарий работает нормально и лучше второго.Файл my.cnf:
innodb_buffer_pool_size = 512M
innodb_thread_concurrency = 16
innodb_thread_sleep_delay = 0
innodb_log_buffer_size = 4M
innodb_flush_log_at_trx_commit=2
Есть идеи, почему оптимизация не увенчалась успехом?