SELECT FOR UPDATE vs. UPDATE, затем SELECT

I ' Мы создали приложение-службу, которое использует многопоточность для параллельной обработки данных, находящихся в таблице InnoDB (около 2–3 миллионов записей и больше никаких запросов, связанных с InnoDB, выполняемых приложением). Каждый поток выполняет следующие запросы к указанной таблице:

  1. НАЧАТЬ ТРАНЗАКЦИЮ
  2. ВЫБРАТЬ ДЛЯ ОБНОВЛЕНИЯ (ВЫБРАТЬ pk ИЗ таблицы WHERE status = 'new' LIMIT 100 FOR UPDATE)
  3. UPDATE (UPDATE table SET status = 'locked 'WHERE pk BETWEEN X AND Y)
  4. COMMIT
  5. DELETE (УДАЛИТЬ ИЗ таблицы WHERE pk BETWEEN X AND Y)

Ребята с forum.percona.com дали мне совет - не используйте SELECT FOR ОБНОВЛЕНИЕ и ОБНОВЛЕНИЕ из-за большего времени, необходимого для выполнения транзакции (2 запроса), и истечения времени ожидания блокировки. Их совет был (автоматическая фиксация включена):

  1. ОБНОВЛЕНИЕ (ОБНОВЛЕНИЕ таблицы SET status = 'заблокировано', thread = Z LIMIT 100)
  2. SELECT (SELECT pk FROM table WHERE thread = Z)
  3. DELETE (УДАЛИТЬ ИЗ таблицы WHERE pk BETWEEN X AND 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

Есть идеи, почему оптимизация не увенчалась успехом?

7
задан Alex 16 February 2011 в 09:41
поделиться