私たちのチームは、先週のデバッグに費やして、多くの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,000ms以上に爆発させるのでしょうか?
*「distinct」なしで*プロファイリングを試しましたか?これを行うにはかなりの労力がかかります。フィルタリングするにはかなりの行があります:) – PhD
非常に良い。 Nopeはそれをしなかった。間違いなくそれを最適化するのに役立ちます。このような遅いクエリがなぜ私たちに多くの問題を引き起こすのかについてはっきりしていません。 – chrishomer
これはなぜ 'IN(item.category_id IS NOT NULL)'が必要なのか不思議です - これは 'INNER JOIN'です - category.idは' NULL 'にすることができます –