MySQL创建临时表然后加入比左连接更快

时间:2014-12-19 16:33:34

标签: mysql sql

我有LEFT JOIN非常贵:

    select X.c1, COUNT(Y.c3) from X LEFT JOIN Y on X.c1=Y.c2 group by X.c1; 

几分钟后(20+),它仍然没有完成。但我想要X中的所有行。所以我确实需要LEFT JOIN

似乎我可以通过在不到两分钟的时间内使用临时表来回复我想要的结果集。我首先修剪表Y,使其只包含连接中的行。

CREATE TEMPORARY TABLE IF NOT EXISTS table2 AS 
(select X.c1 as t, COUNT(Y.c2) as c from X 
INNER JOIN Y where X.c1=Y.c2 group by X.c1);

select X.c1, table2.c from X 
LEFT JOIN table2 on X.c1 = table2.t; 

这在两分钟内结束。

我的问题是:

1)它们是否相同?

2)为什么第二个这么快(为什么MySQL不做这种优化),意思是,我需要做这些类型的mysql吗?

编辑:附加信息:C1,C2为BIGINTS。 C1是唯一的,但可能有许多C2都指向相同的C1。据我所知,我没有索引任何表格。 X.C1是Y.c2所指的_id列。

2 个答案:

答案 0 :(得分:3)

尝试索引X.c1和Y.c2并运行原始查询。

如果没有比较两个查询的查询计划,你很难说没有索引的第一个查询为什么运行得更慢(你可以通过在开头用explain运行查询来获得查询计划)但我怀疑是因为第二个表包含许多在第一个表中没有相应行的行。

答案 1 :(得分:0)

如果x.c1是唯一的,那么我建议将查询编写为:

select X.c1,
       (select COUNT(Y.c3)
        from Y
        where  X.c1 = Y.c2
       )
from X;

对于此查询,您需要Y(c2, c3)上的索引。

left join可能需要更长时间的原因是许多行不匹配。在这种情况下,group by聚合的行数比实际需要的多得多。不,MySQL不会尝试这种类型的优化。