2012-02-07 34 views
3

mysqlのカウントクエリでは、ロード時間を2.5秒から短縮したいと考えています。クエリのすべての列にはインデックスがあります。MySQLカウントの最適化

SELECT COUNT(1) 
FROM song AS s 
JOIN song_text AS st 
    ON(st.song_id = s.song_id) 
JOIN phpfox_user AS u 
    ON(u.user_id = s.user_id) 
WHERE st.lyrics LIKE '%a%' AND s.is_active = 1 AND s.public = 1 

返される行を取得するクエリは、0.0009060秒で読み込まれます。

SELECT s.*, st.lyrics, u.first_name 
FROM song AS s 
JOIN song_text AS st 
    ON(st.song_id = s.song_id) 
JOIN phpfox_user AS u 
    ON(u.user_id = s.user_id) 
WHERE st.lyrics LIKE '%a%' AND s.is_active = 1 AND s.public = 1 
ORDER BY s.date_added DESC 
LIMIT 12 

なぜカウントクエリには、ローを返すクエリよりもかなり多くの読み込み時間がありますか?カウントクエリの読み込み時間を他のクエリと同様のものにするために何ができるのですか?

+0

クエリで 'EXPLAIN'を実行しようとしましたか?これはあなたに洞察を与えるはずです。私は@AdityaNaiduが正しいかもしれないと信じています - 第2のクエリの 'LIMIT'は最初のクエリに必要な多くの作業をフィルタリングしているかもしれません。 – evan

+0

2番目のクエリから 'LIMIT'句を削除し、クエリ時間をポストします。方程式からキャッシュを削除するには、 'SELECT SQL_NO_CACHE <残りのクエリ> 'を使います。 –

+0

2番目のクエリから制限を削除すると、クエリ時間は7.6967690秒になりました。 – user1195817

答えて

0

カウントのu.first_nameの値は気になりますか?いいえ、2番目の結合を削除すると、値を追加しないように見えます。

また、count(1)の代わりにソングテーブルからcount(s.song_id)を試してください。これが本当の最適化か私の想像力なのかどうかは分かりません。

0

2番目のクエリが最初の12個のレコードになると、2番目のクエリが完了します。あなたの最初の(カウント)クエリは、すべてのテーブルのすべての列を結合する必要があります。

これは私が見ることができる唯一の違いです!

0

私はそれはあなただけのselect文の唯一の12行をキャッチするため

LIMIT 12 

のだと思います。

0

最初に、クエリの実行計画を確認する必要があります。

最初のクエリの一時テーブルがかなり大きいと仮定して、集計は大量のデータに適用されます。

もう一方の側では、LIMIT 12は、テンポラリテーブルが小さくなるように、すべての行を作成するのは意味がありませんが、12個しか作成しないことをクエリプロセッサに伝えています。