我们的团队上周刚刚调试并试图找到许多 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 毫秒甚至更高?