2009-09-05 3 views
7

私はmysqlクエリを最適化しようとしていますが、 'filesortを使用して一時的に使用する'のを避けています。私はいくつかの助けをすることができます。最初;ここでここ一時的な使用、filesortを使用してmysqlの悪い考えですか?

を説明するには、関係する2つのテーブルがありますが、クエリ

select pf.*,m.login,m.avatar 
from profile_friends pf, members m 
where pf.friend_id = m.id and pf.member_id = 16586 
order by m.lastLogin desc 
limit 0,24; 


mysql> EXPLAIN select pf.*,m.login,m.avatar from profile_friends pf, members m where pf.friend_id = m.id and pf.member_id = 16586 order by m.lastLogin desc limit 0,24; 
+----+-------------+-------+--------+-----------------------------------------------------+-----------------+---------+--------------------------+------+----------------------------------------------+ 
| id | select_type | table | type | possible_keys          | key    | key_len | ref      | rows | Extra          | 
+----+-------------+-------+--------+-----------------------------------------------------+-----------------+---------+--------------------------+------+----------------------------------------------+ 
| 1 | SIMPLE  | pf | ref | member_id_index,friend_id_index      | member_id_index |  4 | const     | 160 | Using where; Using temporary; Using filesort | 
| 1 | SIMPLE  | m  | eq_ref | PRIMARY,member_id_privacy_index,id_last_login_index | PRIMARY   |  4 | mydb.pf.friend_id  | 1 | Using where         | 

です。プロフィール友人(pf)、およびメンバー(m)。このクエリは、この特定のメンバーIDの '最近の' 24人の友だちを検索しようとしています。最近の手段はLastLoginの日付で並べ替えます。

ありがとうございました

答えて

17

問題ですか?うん。

160行を扱うときに問題がありますか?いいえ。

"ファイルルート"は、ファイルの実際の作成およびソートではなく、方法です。 160行ではなく160,000行を使用している場合は、さらに最適化を検討する必要があります。

編集:実際のクエリの実行時間も省略しました。あなたはインデックスを叩いており、一握りの行だけで作業しています。このクエリで1秒間に数分の1秒以上かかる場合は、最適化を検討する価値はないでしょう。

+3

+1はい、160行です。MySQLは、一時テーブルをディスクに書き込まずにメモリに保持することさえあります。 "Filesort"は少し誤解を招くだけで、インデックスの利点なしにソートすることを意味します。 –

1

これは、そのクエリを書くための最も効率的な方法です。

pf.friend_idpf.member_id、およびm.idにインデックスが付いていることを確認してください。次に、インデックスを使用してテーブルを結合し、結果をフィルタリングします。

あなたのorder byのために、とにかく、その並べ替えが表示されます。

+4

MySQLは 'pf.friend_id'上のインデックスか' pf.member_id'上のインデックスのどちらかを使用しますが、両方を使用することはないので余分なインデックスを作成する必要はありません。しかし、それは '(member_id、friend_id)'にインデックスを使うことができます。 –

2

あなたのEXPLAINによって、それはあなたがすでにそれを試みたようだ私はあなたがそのため—でmembers (id,lastLogin)—上のインデックスを持つ一時的/ filesortレコードを避けることができるはずだと思いますが、クエリのそのタイプのためにそれはやり過ぎだと判断しますか?

profile_friends (member_id,friend_id)のPRIMARY/UNIQUE KEYで補完し、その動作を確認してください。最後に

そのクエリは、そう頻繁に、あなたが最速SELECT持っている必要がありますので、多くのレコードに実行された場合、あなたはあなたのテーブルを非正規化し、(member_id,lastLogin)のインデックスとprofile_friendsにごmembers.lastLogin列のコピーを追加することができます。それで、あなたは結合も、ファイルも、何もないでしょう。一方、多くの友人を持つ人がログインするたびに大きなUPDATEクエリが表示されます。これは、あなたが話している種類の数字については、まったく残忍なようです。

私はほとんど元の質問に対処するのを忘れます。mysqlに悪い考えをfilesortレコード使用して、一時的に使用

を?

いいえ、そうではありません。それを簡単に最適化できれば、 "filesort-free"クエリを常に探すべきですが、実際のパフォーマンス上の問題が発生しない限り、それを心配する必要はありません。 Filesortは、通常のクエリの実行の一部です。

関連する問題