今、mixiのマイページの「新着の更新情報」と同等の機能を実装しているのですが
動作がもっさりしてしまいます。
副クエリを使用して、ユーザー毎の最新の情報を取得しております。
下記の様な形で書いております。
※一部を抜粋しておりますため、間違いがあるかもしれません。
SELECT * FROM メッセージを扱うテーブル名 a
WHERE (a.ユーザーID名,a.日付のフィールド名) IN(SELECT a.ユーザーID名,max(o.日付のフィールド名) FROM メッセージを扱うテーブル名 o GROUP BY o.ユーザーID名)
ORDER BY a.日付のフィールド名 DESC;
ただ、mixiと同様に、公開制限などもあるため、それを副クエリ側に入れております。
何か、良い改善方法はございませんでしょうか?
a.ユーザーID名,a.日付のフィールド名でindexは作成してありますか?
もし未作成ならば作成することでパフォーマンスが改善します。
urlはダミーです
サブクエリは一度展開されてしまうので対象レコードを絞り込んだほうがよいように思われます
WHERE o.ユーザーID名 = a.ユーザーID名
GROUP BYでは対象レコードを総なめしてしまうので、逆から1レコード目だけを取得するほうがよいように思われます
ORDER BY o.日付のフィールド名 DESC LIMIT 0,1
SELECT * FROM メッセージを扱うテーブル名 a WHERE a.日付のフィールド名 = (SELECT o.日付のフィールド名 FROM メッセージを扱うテーブル名 o WHERE o.ユーザーID名 = a.ユーザーID名 ORDER BY o.日付のフィールド名 DESC LIMIT 0,1) ORDER BY a.日付のフィールド名 DESC;
LIMITよりもMAXだけのほうが高速かもしれません
SELECT * FROM メッセージを扱うテーブル名 a WHERE a.日付のフィールド名 = (SELECT max(o.日付のフィールド名) FROM メッセージを扱うテーブル名 o WHERE o.ユーザーID名 = a.ユーザーID名) ORDER BY a.日付のフィールド名 DESC;
オリジナルならびに上記2例で比較してみてください
相当高速化されました!
ありがとうございます。
SQLチューニングの手法で、
「INよりもEXISTSの法が速い」
というものがあります。
http://www.geocities.jp/mickindex/database/db_optimize.html#Loca...
拝見したところこのクエリでは確かに遅い気がします。
MS系のRDBがこの記述でも早かったかと・・
副問合せ
IN(SELECT a.ユーザーID名,max(o.日付のフィールド名)
これをwhere句の中ではなく、
fromの中に入れるとレスポンスが向上します
SELECT * FROM メッセージを扱うテーブル名 a,
(SELECT a.ユーザーID名,max(o.日付のフィールド名) mmax FROM メッセージを扱うテーブル名 o GROUP BY o.ユーザーID名) aa
WHERE (a.ユーザーID名,a.日付のフィールド名) = aa.mmax
ORDER BY a.日付のフィールド名 DESC;
もっと具体的に
SELECT at.ユーザーID名,at.日付のフィールド名,aa.mmaxdt FROM メッセージを扱うテーブル名 a at,
(SELECT a.ユーザーID名,max(o.日付のフィールド名) mmaxdt FROM メッセージを扱うテーブル名 o GROUP BY o.ユーザーID名) aa
WHERE (a.ユーザーID名,a.日付のフィールド名) = aa.mmaxdt
ORDER BY 2 DESC;
※参考イメージで、あくまで一例です。
要はビューを一つ定義し、fromのなかにエイリアスとして配置することです。
※この場合、aaがINの中に入っていたselect文のエイリアスになります。
試してみてください。
http://jibun.atmarkit.co.jp/lskill01/rensai/bronzesql09/bronzesq...
はい。しております。。。
副クエリ内でも、公開制限などのために、テーブルの連結をしており、
そこももっさりの原因の一つのようです。。