これは私のWebアプリケーションではるかに遅いクエリです。
SELECT prof.user_id AS userId,
prof.first_name AS first,
prof.last_name AS last,
prof.birthdate,
prof.class_string AS classes,
prof.city,
prof.country,
prof.state,
prof.images,
prof.videos,
u.username,
u.avatar,
(SELECT Count(*)
FROM company_member_sponsorship
WHERE member_id = prof.user_id
AND status = 'sponsored') AS sponsor_count,
(SELECT Count(*)
FROM member_schedules
WHERE user_id = prof.user_id) AS sched_count
FROM member_profiles prof
LEFT JOIN users u
ON u.id = prof.user_id
ORDER BY ( prof.images + prof.videos * 5 + (
CASE
WHEN prof.expire_date > :time THEN 50
ELSE 0
end ) + sponsor_count * 20 + sched_count * 4
) DESC,
prof.last_name ASC
LIMIT :start, :records
すべてのレベルで多くのクエリが発生している場合でも、サイト上の他のすべてのものをロードするのに1秒もかかりません。これは約3〜4秒かかります。
明らかに、速度低下の原因となっているのはテーブルスキャンです。理由は理解できます。最初のテーブルには50,000以上の行があり、2番目のテーブルには160,000以上の行があります。
このクエリを最適化して高速化する方法はありますか?
最悪の場合、私はいつでもコードを調べて、画像やビデオの場合と同じように、プロファイルテーブルでスポンサーシップやイベントの集計を維持できますが、それは避けたいと思います。
編集:EXPLAINの結果をクエリに追加しました。
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY prof ALL NULL NULL NULL NULL 44377 Using temporary; Using filesort
1 PRIMARY u eq_ref PRIMARY PRIMARY 3 mxsponsor.prof.user_id 1
3 DEPENDENT SUBQUERY member_schedules ref user_id user_id 3 mxsponsor.prof.user_id 6 Using index
2 DEPENDENT SUBQUERY company_member_sponsorship ref member_id member_id 3 mxsponsor.prof.user_id 2 Using where; Using index
EDIT2:
メンバープロファイルのカウントを維持することで問題に対処することになりました。スポンサーシップ/イベントが追加/削除される場合は常に、スポンサーシップ/イベントテーブルをスキャンしてそのメンバーのカウントを更新する関数を呼び出すだけです。このようなクエリを最適化する方法はまだあるかもしれませんが、このサイトはもうすぐ公開されるので、今のところは迅速で汚い解決策を使用します。