クエリは次のとおりです。
SELECT
u.uid as UID,
fuo.uid as FUO_UID,
fo.prid as FO_NAME
FROM
users u
LEFT OUTER JOIN firstpoint_users_organisations fuo ON (u.uid=fuo.uid)
LEFT OUTER JOIN firstpoint_organisations fo ON (fo.nid=fuo.nid)
WHERE
u.status=1 AND u.uid>1
ORDER BY u.uid
LIMIT 3;
そしてテーブル:
users
+------------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+------------------+------+-----+---------+----------------+
| uid | int(10) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(60) | NO | UNI | | |
| status | tinyint(4) | NO | | 0 | |
+-----------------------------------------------------------------------------+
firstpoint_users_organisations
+-------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+-------+
| nid | int(10) unsigned | NO | PRI | 0 | |
| uid | int(10) unsigned | NO | PRI | 0 | |
+-------+------------------+------+-----+---------+-------+
firstpoint_organisations
+----------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+------------------+------+-----+---------+-------+
| nid | int(10) unsigned | NO | PRI | 0 | |
| prid | varchar(32) | NO | | | |
+------------------------------------------------------------+
一部のユーザーが を持たない場合でも、のすべての行に対してusers.uid
andを表示したいのですが、その場合は NULL を表示します (したがって、左外部結合)。接続は次のようにする必要があります。firstpoint_organisations.prid
users
prid
users
uid - firstpoint_users_organisations
\---->uid
nid - firstpoint_organisations
\-------->nid
prid
したがって、各ユーザー (users) にはユーザー ID (uid) があり、関連付けられている組織 (firstpoint_users_organisation) にはノード ID (nid) があり、この関連付けを保存します。組織の詳細は firstpoint_organisations に保存されます。
したがって、すべてのユーザーには がありますが、prid
そうでない場合は NULL が表示されます。
ここで、 で INNER JOIN を実行するfirstpoint_users_organisations
と、firstpoint_organisations
クエリ速度が向上します (上記のクエリは 0.02 秒で実行されます)。しかし、両方を LEFT OUTER JOIN に切り替えて、すべてのユーザーを取得できるようにするprid
か、 noを取得するprid
と、上記のクエリの実行に約 90 秒かかります。
このクエリを高速化するためにできることはありますか? 約あります。テーブルには 70,000 行ありusers
ますが、LIMIT 3 を使用しても、INNER JOIN を LEFT OUTER JOIN にするのに恐ろしいほどの時間がかかります。興味深いことに、LIMIT 30 でクエリを実行するのに同じ時間がかかるため、クエリに根本的な問題があると思います。
要求に応じて説明:
+----+-------------+-------+--------+---------------+---------+---------+-----------------------+-------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+---------------+---------+---------+-----------------------+-------+----------------------------------------------+
| 1 | SIMPLE | u | range | PRIMARY | PRIMARY | 4 | NULL | 13152 | Using where; Using temporary; Using filesort |
| 1 | SIMPLE | fuo | index | NULL | PRIMARY | 8 | NULL | 3745 | Using index |
| 1 | SIMPLE | fo | eq_ref | PRIMARY | PRIMARY | 4 | dbdb-dbdb_uat.fuo.nid | 1 | |
+----+-------------+-------+--------+---------------+---------+---------+-----------------------+-------+----------------------------------------------+
3 rows in set (0.00 sec)