我們的團隊剛剛花了最後一週的時間進行調試,並試圖找到許多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)
我可以看到它正在做一個討厭的表掃描並創建一個臨時表來運行。
爲什麼此查詢會導致數據庫響應時間增加10倍,而某些查詢通常需要40-50ms(項目表上的更新),有時會爆炸至50,000毫秒或更高?
您是否嘗試過分析*而沒有*'distinct'?這需要相當多的工作,並且你有相當多的行來過濾:) – PhD
非常好。 Nope沒有這樣做。它絕對有助於優化它。仍然不清楚爲什麼這樣一個緩慢的查詢會導致我們很多問題。 – chrishomer
只是想知道爲什麼你需要這個'AND(items.category_id不是NULL)' - 因爲它是一個'INNER JOIN' - 是category.id允許爲'NULL' –