这是查询:
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
和,即使某些用户没有,在这种情况下我显示 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 onfirstpoint_users_organisations
然后 on firstpoint_organisations
,我会得到很好的查询速度(上面的查询在 0.02 秒内运行)。但是,当我将两者都切换到 LEFT OUTER JOIN 时,我可以获得所有用户,prid
或者没有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)