繁体   English   中英

MySQL查询优化:多个SELECT IN到LEFT JOIN

[英]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和用户的所有分配。 然后,您要查找的用户位于a2p 我添加了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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM