[英]MySQL query optimization: Multiple SELECT IN to LEFT JOIN
我通常采用join
方法,但在这种情况下我有点困惑。 我什至不确定这是否有可能。 我想知道以下查询是否可以转换为left join
查询,而不是使用的多select in
查询:
select
users.id, users.first_name, users.last_name, users.description, users.email
from users
where id in (
select assigned.id_user from assigned where id_project in (
select assigned.id_project from assigned where id_user = 1
)
)
or id in (
select projects.id_user from projects where projects.id in (
select assigned.id_project from assigned where id_user = 1
)
)
该查询返回正确的结果集。 但是,我猜选择选择assigned.id_project
的查询的重复是浪费的。
您可以从用户1 a1
的项目分配开始。 然后在项目表p
找到其他人对那些项目a2
和用户的所有分配。 然后,您要查找的用户位于a2
或p
。 我添加了distinct,以删除可以通过两种方式访问的用户。
select distinct u.*
from assigned a1
left join
assigned a2
on a1.id_project = a2.id_project
left join
project p
on a1.id_project = p.id
join user u
on u.id = a2.id_user
or u.id = p.id_user
where a1.id_user = 1
由于两个子查询都有一个条件,其中named.id_user = 1,因此我从该查询开始。 让我们将该作业称为“主要作业”。
然后使用“可选”表的左联接来联接其余的联接。 在user
上使用内部联接,该内部联接与链接到主要任务的任务用户或链接到主要项目的项目user
匹配。
我使用“与众不同”,因为我假设您希望每个用户一次,如果他们有一个任务和一个项目(或多个项目),则为事件。
select distinct
u.id, u.first_name, u.last_name, u.description, u.email
from
assigned a
left join assigned ap on ap.id_project = a.id_project
left join projects p on p.id = a.id_project
inner join users u on u.id = ap.id_user or u.id = p.id_user
where
a.id_user = 1
这是摆脱重复的另一种方法:
SELECT
users.id,
users.first_name,
users.last_name,
users.description,
users.email
FROM users
WHERE id IN (
SELECT up.id_user
FROM (
SELECT id_user, id_project FROM assigned
UNION ALL
SELECT id_user, id FROM projects
) up
INNER JOIN assigned a
ON a.id_project = up.id_project
WHERE a.id_user = 1
)
;
也就是说, assigned
表的双id_user, id_project
被合并与那些projects
。 然后将结果集与user_id = 1
项目结合在一起,以获得与ID 1用户共享项目的所有用户的列表。 现在只剩下检索这些用户的详细信息了,在这种情况下,这与查询中的方法相同,即使用IN子句。
很遗憾地说,我没有MySQL可以全面测试该查询的性能,因此不能完全确定它是否比您的原始查询好,或者比@GolezTrol和通过@Andomar 。 通常,我倾向于同意@GolezTrol的评论 ,即具有简单(半或任意)连接和重复部分的查询可能比没有重复的等效复杂查询更有效。 然而,最后,测试必须为您揭示最终答案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.