9

MySQL 5.5.25 サーバーと、データベースに InnoDB を使用しています。

約 1 分間の mysqld プロセスが原因で、サーバーの CPU が 100% で動作していることがよくあります。SHOW PROCESSLIST の使用:

Command | Time | State        | Info
Query   |  100 | Sending data | SELECT a.prefix, a...
Query   |  107 | Sending data | SELECT a.prefix, a...
Query   |   50 | Sending data | SELECT a.prefix, a...

問題のあるクエリは次のとおりです。

SELECT a.prefix, a.test_id, a.method_id, b.test_id
FROM a
LEFT JOIN b ON b.test_id = a.test_id
AND user_id = ?
AND year = ?

これらの列はすべて INDEXED であるため、これは問題ではありません。また、phpMyAdmin で (十分な LIMIT を使用して) クエリを実行すると、完了するまでに 0.05 秒かかります。また、このクエリを同時に 2 回実行し、スパムを送信しても CPU が 40% しか上昇しない場合でも、この問題を自分で再現するのは不可能であることがわかり、非常にイライラします。

クエリの前に EXPLAIN を付けると、次のようになります。

Id | select_type | table | type | possible_keys        | key     | key_len | ref          | rows | Extra
 1 | SIMPLE      | a     | ALL  | NULL                 | NULL    | NULL    | NULL         | 1169 | 
 1 | SIMPLE      | b     | ref  | user_id,year,test_id | test_id | 4       | db.a.test_id |   58 | 

目の前にあるものが見えない限り、この種の問題をデバッグする方法を見つける方法を探しています。すべてのクエリの実行時間や値などを既にログに記録していますが、再現できないため、行き詰まっています。この問題が何であるかを理解するにはどうすればよいですか?

4

2 に答える 2

8

うわー、Masood Alam のコメントのおかげで、問題を見つけて解決しました。

を使用SHOW ENGINE INNODB STATUSすると、デバッグに非常に役立ちます。

データベースの一部の値でuser_idは処理が異なるため、予期しない動作が発生し、問題を再現できないことが判明しました。status コマンドを使用して、現在実行中の正確なクエリをコピーして貼り付けることができました。

これは、 のEXPLAIN特定の値の結果user_idです。

Id | select_type | table | type         | possible_keys        | key          | key_len | ref  | rows | Extra
 1 | SIMPLE      | a     | ALL          | NULL                 | NULL         | NULL    | NULL |  841 | 
 1 | SIMPLE      | b     | index_merge  | user_id,year,test_id | user_id,year | 4,4     | NULL |   13 | Using intersect(user_id,year); Using where

フォローアップの質問は、この動作をどのように説明できるかです。ただし、問題を解決するには、クエリを次のように変更するだけでした。

SELECT a.prefix, a.test_id, a.method_id, b.test_id
FROM a
LEFT JOIN b ON b.test_id = a.test_id
WHERE
b.id IS NULL
OR user_id = ?
AND year = ?

そのうちのEXPLAIN結果:

Id | select_type | table | type | possible_keys | key     | key_len | ref          | rows | Extra
 1 | SIMPLE      | a     | ALL  | NULL          | NULL    | NULL    | NULL         |  671 | 
 1 | SIMPLE      | b     | ref  | test_id       | test_id | 4       | db.a.test_id |   49 | Using where

これで、InnoDB は、異なる入力値を指定してクエリを実行するためのさまざまなアプローチを持つことができることがわかりました。なんで?まだわかりません。

于 2013-10-04T12:32:56.740 に答える