3

最近、これまで見たことのない問題が発生しました。約 3 時間、Mysql テーブルの 1 つが非常に遅くなりました。このテーブルはフォーラムの投稿を保持し、現在約 100 万行あります。遅くなったクエリは、私たちのアプリケーションで非常に一般的なものでした:

SELECT * FROM `posts` WHERE (`posts`.forum_id = 1)  ORDER BY posts.created_at DESC LIMIT 1;

(forum_id、created_at)のpostsテーブルにインデックスがあり、通常、このクエリとソートをメモリ内で実行できます。しかし、この 3 時間はそれほどでもありません。通常、この時間内に 2 秒から 45 秒かかる瞬間的なクエリです。その後、正常に戻りました。

スロー クエリ ログに目を通しましたが、他に異常は見られません。私は New Relic (これは Rails アプリです) を調べましたが、他のすべてのアクションは基本的に通常と同じ速度で実行されました。今日は異常な数のメッセージ投稿はありませんでした。ログには他に奇妙なものは見つかりません。また、使用可能なメモリがまだギグある場合、データベースはスワッピングしていませんでした。

Mysql が特定のクエリに使用するインデックスについて考えを前後に変更できるかどうか疑問に思っています。なんらかの理由で、今日数時間、このクエリで完全なテーブル スキャンを実行することを決定し始めましたか? しかし、それが本当なら、なぜテーブル全体のスキャンを停止したのでしょうか?

他の誰かが理由に反する断続的に遅いクエリに遭遇しましたか? または、このような問題をデバッグする方法について何か独創的なアイデアはありますか?

4

2 に答える 2

2

MySQLEXPLAINステートメントを試してみます...

EXPLAIN SELECT * FROM `posts` WHERE (`posts`.forum_id = 1)  ORDER BY posts.created_at DESC LIMIT 1;

RailsコードでMySQLの応答時間を確認する価値があるかもしれません。それがしきい値を超えている場合は、を実行しEXPLAINて詳細をどこかに記録します。

テーブルのロックも頭に浮かびます-SELECTが実行されている間、postsテーブルはcronjobまたは大量のクエリによって更新されますか?

それが少し役立つことを願っています!

于 2009-08-10T10:16:51.577 に答える
2

私が取り組んでいるサイトで、最近MyISAMからInnoDBに切り替えましたが、WHERE句とORDER BY句の両方を持ついくつかの単純なselectクエリが、ORDER BY句のインデックスを使用していることがわかりました。その結果、テーブルスキャンでいくつかが見つかりました。必要な行(ただし、最終的にすべてが見つかったときに並べ替える必要はありませんでした!)

リンク先の記事に記載されているように、LIMIT値が小さい場合、ORDER BY句は主キーの最初のメンバーであり(ファイル上のデータはそれによって順序付けられます)、WHERE句に一致する結果が多数あります。そのORDERBYインデックスを使用することは、MySQLにとって悪い考えではありません。ただし、created_atは主キーの最初のメンバーではないと思います。したがって、この場合は特に賢明なアイデアではありません。

何も変更していないのにMySQLがインデックスを切り替える理由はわかりませんが、関連するテーブルでANALYZETABLEを実行してみることをお勧めします。結果セットが十分に小さい場合は、クエリを変更してLIMIT句とORDER BY句を削除し、アプリケーションレベルで並べ替えることもできます。または、USE INDEXヒントを追加して、間違った推測をしないようにすることもできます。

また、wait_timeout値を小さい値に変更して、不正なインデックスを使用するこれらのクエリが完了しないようにすることもできます(ただし、正当なクエリのすべてに遅れをとらないようにしてください)。個別の構成パラメーターがあるため、wait_timeoutが小さい場合でも、長いクエリをインタラクティブに実行できます。

于 2009-08-10T10:23:59.253 に答える