複数のテーブルのどれかに紐付いているデータを出力する(速度改善)

MySQLで速度改善の事例が見つかったのでメモ

テーブル構成

  • users
    • ユーザー
  • clubs
    • 部活
  • councils
    • 生徒会
mysql> DESC users
+------------------+------------------+------+-----+---------+----------------+
| Field            | Type             | Null | Key | Default | Extra          |
+------------------+------------------+------+-----+---------+----------------+
| id               | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| name             | varchar(200)     | NO   |     |         |                |
+------------------+------------------+------+-----+---------+----------------+

mysql> DESC club_member_settings
+------------------+------------------+------+-----+---------+----------------+
| Field            | Type             | Null | Key | Default | Extra          |
+------------------+------------------+------+-----+---------+----------------+
| user_id          | int(10) unsigned | NO   |     |         |                |
| club_id          | int(10) unsigned | NO   |     |         |                |
+------------------+------------------+------+-----+---------+----------------+

mysql> DESC council_member_settings
+------------------+------------------+------+-----+---------+----------------+
| Field            | Type             | Null | Key | Default | Extra          |
+------------------+------------------+------+-----+---------+----------------+
| user_id          | int(10) unsigned | NO   |     |         |                |
| council_id       | int(10) unsigned | NO   |     |         |                |
+------------------+------------------+------+-----+---------+----------------+

やりたいコト

部活か生徒会に所属しているユーザーを取得したい

安直な方法

SELECT users.*
FROM users
  LEFT JOIN club_member_settings ON users.id = club_member_settings.user_id
  LEFT JOIN council_member_settings ON users.id = council_member_settings.user_id
WHERE
  club_member_settings.id IS NOT NULL OR
  council_member_settings.id IS NOT NULL
GROUP BY users.id
問題点

club_member_settings/council_member_settingsの数が多い場合、速度の劣化が激しい
おそらく、JOINの段階では絞れず、OR条件なので計算数が多くなるから?かなと思っていますが、詳しい方がいらっしゃいましたら、ご教示頂けますと幸いです。

速度改善が見込める方法

SELECT users.*
FROM users
  INNER JOIN club_member_settings ON users.id = club_member_settings.user_id
UNION SELECT users.*
FROM users
  INNER JOIN council_member_settings ON users.id = council_member_settings.user_id
ポイント

INNER JOINを行っている段階で、usersが絞り込まれる
また、UNIONすることで検索条件のORを満たすことができ、かつユニークにもなる


ご参考になれば幸いです。
最後までお読み頂きありがとうございました。