Наша команда просто провела последнюю неделю отладки и попыталась найти источник многих тайм-аутов блокировки mysql и многих чрезвычайно длинных запросов. В конце концов, похоже, этот запрос является виновником.
mysql> explain
SELECT categories.name AS cat_name,
COUNT(distinct items.id) AS category_count
FROM `items`
INNER JOIN `categories` ON `categories`.`id` = `items`.`category_id`
WHERE `items`.`state` IN ('listed', 'reserved')
AND (items.category_id IS NOT NULL)
GROUP BY categories.name
ORDER BY category_count DESC
LIMIT 10\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: items
type: range
possible_keys: index_items_on_category_id,index_items_on_state
key: index_items_on_category_id
key_len: 5
ref: NULL
rows: 119371
Extra: Using where; Using temporary; Using filesort
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: categories
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: production_db.items.category_id
rows: 1
Extra:
2 rows in set (0.00 sec)
Я вижу, что он делает неприятное сканирование таблицы и создает временную таблицу для запуска.
Почему этот запрос заставляет время ответа базы данных увеличиваться в десять раз и некоторые запросы, которые обычно занимают 40-50 мс (обновления в таблице элементов), взорваться до 50 000 мс и выше в разы?