MySQLがインデックスを使用する方法 を参照してください。 。
以前の投稿とは異なり 、MySQLもコストベースのオプティマイザーを使用している
ことがわかりました。 、これは非常に良いニュースです。つまり、ANALYZE
を実行している場合です。 データベース内のデータの量が代表的であると思われる場合は、少なくとも1回は 将来の日常使用の。
コストベースのオプティマイザ(Oracle、Postgresなど)を扱う場合は、定期的に ANALYZE
サイズが10〜15%以上増加すると、さまざまなテーブルで使用できます。 (Postgresはデフォルトでこれを自動的に行いますが、他のRDBMSはこの責任をDBA、つまりあなたに任せます。)統計分析を通じて、ANALYZE
オプティマイザーは、さまざまな候補実行プランから選択するときに、どのくらいのI / O(およびCPUなど、ソートなどに必要な他の関連リソース)が関与するかをより正確に把握するのに役立ちます。 ANALYZE
の実行に失敗しました 計画の決定が非常に貧弱で、時には悲惨な結果になる可能性があります(たとえば、ネストされたループが不適切なため、クエリに数時間かかる場合があります。 JOIN
で s。)
ANALYZE
を実行した後も、パフォーマンスがまだ不十分な場合 、その後、通常、ヒントを使用して問題を回避できます。 FORCE INDEX
、一方、他の場合には、MySQLのバグに遭遇した可能性があります(例:この古いバグ 、Railsのnested_set
を使用していると思われるかもしれません。 。
さて、Railsアプリを使用しているので 、それは面倒になります(そしてActiveRecord
の目的を打ち負かします )ActiveRecord
を引き続き使用する代わりに、ヒントを使用してカスタムクエリを発行します -生成されたもの。
Railsアプリケーションですべて SELECT
Postgresに切り替えた後、クエリは100ミリ秒未満に低下しましたが、ActiveRecord
によって生成された複雑な結合の一部は インデックスが利用可能な場合でも、内部テーブルスキャンを使用したネストされたループのため、MySQL5.1では15秒以上かかる場合がありました。完璧なオプティマイザはありません。オプションに注意する必要があります。クエリプランの最適化に加えて、注意すべきその他の潜在的なパフォーマンスの問題はロックです。ただし、これは問題の範囲外です。