设置我的模式,使我有三个表player coachmanager,其中所有三个表均具有表employee的外键,该表包含不超过一个自动递增ID和字符串代表他们是雇员的类型。 “玩家”或“教练”或“经理”。

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

为了从他们的团队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%!并集不是必须在所有三个表上都选择,而交叉引用查询将注意到三个联接之一是可能的,而丢弃了另外两个联接?

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

编辑

我的数据库中大约有30,000个元素,我在通过通过联合查询我的数据的前半部分和通过联接查询下半部分的数据来进行计时。对于联合,我的时间大约为3.9秒,对于联接,我的时间为7.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

关于mysql - 为什么对三个表的联合mysql查询比不可能的where子句连接要快?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38569946/

10-12 22:34
查看更多