私は自分の大学の Web サイト用のアプリケーションを開発しており、データベースからすべてのイベントを日付の昇順で取得したいと考えています。合計 4 つのテーブルがあります。
テーブル イベント1
event_id, mediumint(8), Unsigned
date, date,
Index -> Primary Key (event_id)
Index -> (date)
テーブル events_users
event_id, smallint(5), Unsigned
user_id, mediumint(8), Unsigned
Index -> PRIMARY (event_id, user_id)
表 user_bm
link, varchar(26)
user_id, mediumint(8)
Index -> PRIMARY (link, user_id)
テーブル user_eoc
link, varchar(8)
user_id, mediumint(8)
Index -> Primary (link, user_id)
クエリ:
EXPLAIN SELECT * FROM events1 E INNER JOIN event_users EU ON E.event_id = EU.event_id
RIGHT JOIN user_eoc EOC ON EU.user_id = EOC.user_id
INNER JOIN user_bm BM ON EOC.user_id = BM.user_id
WHERE E.date >= '2013-01-01' AND E.date <= '2013-01-31'
AND EOC.link = "E690"
AND BM.link like "1.1%"
ORDER BY E.date
説明:
上記のクエリは 2 つのことを行います。
1) user_bm および user_eoc テーブルを介してすべての学生を検索して除外します。「リンク」列は、専攻/学年/キャンパスなどで学生をすばやくフィルタリングするための非正規化列です。
2) フィルターを適用した後、MYSQL は一致するすべての学生の user_id を取得し、参加しているすべてのイベントを見つけて、昇順で出力します。
クエリ オプティマイザーの説明:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE EOC ref PRIMARY PRIMARY 26 const 47 Using where; Using index; Using temporary; Using f...
1 SIMPLE BM ref PRIMARY,user_id-link user_id-link 3 test.EOC.user_id 1 Using where; Using index
1 SIMPLE EU ref PRIMARY,user_id user_id 3 test.EOC.user_id 1 Using index
1 SIMPLE E eq_ref PRIMARY,date-event_id PRIMARY 3 test.EU.event_id 1 Using where
質問:
クエリは正常に機能しますが、最適化できます。具体的には、ファイルソートを使用して一時的に使用するとコストがかかるため、これを避けたいと思います。一致するユーザーと 1:n の関係にあるイベントを日付で「並べ替え」たいので、これが可能かどうかはわかりません。Order BY は、結合されたテーブルに適用されます。
ヘルプやガイダンスをいただければ幸いです。ありがとう、ハッピーホリデー!