为什么对三个表的联合mysql查询比在不可能的where子句中加入更快?

时间:2016-07-25 14:06:59

标签: mysql database join union

我的架构设置为我有三个表player coachmanager,其中所有三个表都有一个表employee的外键,其中包含不超过一个自动递增的id和一个字符串type,表示他们的雇员类型即。 'PLAYER'或'COACH'或'MANAGER'。

但是,不同的员工根据他们所工作的团队有不同的ID。因此,每个团队都有一个查找表team_x_lookup(其中x是团队编号或名称),它将团队ID映射到全局ID。另外,对于每个包含团队ID的团队,我在每个player coachmanager表中都有一个生成的列,此列已编入索引。如果员工不在该团队中,该栏显然为空。

要从团队ID中获取员工,我目前有两个选择语句

SELECT * FROM employee e
    LEFT JOIN player p ON (e.`type` = 'PLAYER' AND p.employee_id = e.id)
    LEFT JOIN coach c ON (e.`type` = 'COACH' AND c.employee_id = e.id)
    LEFT JOIN manager m ON (e.`type` = 'MANAGER' AND m.employee_id = e.id)
WHERE e.id = (
    SELECT employee_id FROM team_x_lookup t WHERE t.team_id = 6
);

SELECT * FROM (
    SELECT * FROM player WHERE team_id = 6 
    UNION
    SELECT * FROM coach WHERE team_id = 6
    UNION 
    SELECT * FROM manager WHERE team_id = 6
) as emp;

我对SELECT的所有内容都有索引。运行解释分别给了我这些:

1   PRIMARY e       const   PRIMARY,id_UNIQUE           PRIMARY 4   const   1   100.00  
1   PRIMARY p       const   PRIMARY,employee_id _UNIQUE PRIMARY 4   const   1   100.00  
1   PRIMARY c       const   PRIMARY,employee_id _UNIQUE PRIMARY 4   const   0   0.00    unique row not found
1   PRIMARY m       const   PRIMARY,employee_id _UNIQUE PRIMARY 4   const   0   0.00    unique row not found
2   SUBQUERY t      const   PRIMARY,team_id_UNIQUE      PRIMARY 4   const   1   100.00  

1   PRIMARY         <derived2>      ALL                                 6               100.00  
2   DERIVED         player          ref team_x_id_INDEX team_x_id_INDEX 5   const   1   100.00  Using index
3   UNION           coach           ref team_x_id_INDEX team_x_id_INDEX 5   const   1   100.00  Using index
4   UNION           manager         ref team_x_id_INDEX team_x_id_INDEX 5   const   1   100.00  Using index
N   UNION RESULT    <union2,3,4>    ALL                                                         Using temporary

我不喜欢第二种方式,因为它要求我为每个表增加20个列。但是,我不明白联合查询如何比查询表查询快50%!联合不是必须在所有三个表上进行选择,而交叉引用查询会注意到三个联接中的一个是可能的并且丢弃其他两个表吗?

我想知道如何使交叉引用表更快,另外因为union要求我从union中的每个表中选择相同数量的列,而我的每个表都有不同数量的列,所有列都应该是返回。

修改

我在数据库中有大约30,000个元素,我通过联合查询我的数据的前半部分,通过联接查询后半部分,从而完成我的计时。我的时间大约是联盟的3.9s和联盟的7.0s。

1 个答案:

答案 0 :(得分:0)

您可以通过删除子查询来提高第一个查询的效率,如下所示:

SELECT e.* FROM employee e
INNER JOIN team_x_lookup t ON e.id = t.employee_id
LEFT JOIN player p ON (e.`type` = 'PLAYER' AND p.employee_id = e.id)
LEFT JOIN coach c ON (e.`type` = 'COACH' AND c.employee_id = e.id)
LEFT JOIN manager m ON (e.`type` = 'MANAGER' AND m.employee_id = e.id)
WHERE t.team_id = 6