如何在左连接上优化mysql

时间:2016-09-06 11:01:57

标签: mysql query-optimization

我试着解释一个非常高的水平

我有两个复杂的SELECT查询(为了示例,我将查询减少到以下内容):

SELECT id, t3_id FROM  t1;
SELECT t3_id, MAX(added) as last FROM t2 GROUP BY t3_id;

查询1返回16k行,查询2返回15k

每个查询单独花费1 second来计算

然而,当我尝试使用added

时,我需要使用查询2的列LEFT join对结果进行排序
SELECT 
    t1.id, t1.t3_Id
FROM
    t1
        LEFT JOIN
    (SELECT t3_id, MAX(added) as last FROM t2 GROUP BY t3_id) AS t_t2 
        ON t_t2.t3_id = t1.t3_id
GROUP BY t1.t3_id
ORDER BY t_t2.last

但是,执行时间会超过1 minute

我想了解原因

这么大爆炸的原因是什么?

注意:

每个表上所有已使用的列都已编制索引 例如:

  • 表t1具有id,t3_Id
  • 的索引
  • 表t2在t3_id上有索引并添加了

EDIT1

在@Tim Biegeleisen建议之后,我将查询更改为以下,现在查询正在大约16秒内执行。如果我删除ORDER BY,则查询会在不到1秒的时间内执行。问题是ORDER BY唯一的原因。

SELECT 
    t1.id, t1.t3_Id
FROM
    t1
        LEFT JOIN
    t2 ON t2.t3_id = t1.t3_id

GROUP BY t1.t3_id
ORDER BY MAX(t2.added)

3 个答案:

答案 0 :(得分:1)

即使表t2在列t3_id上有索引,但当您加入t1时,您实际上正在加入一个派生表,该表无法使用索引,或者可以完全有效地使用它。由于t1有16K行且您正在执行LEFT JOIN,这意味着数据库引擎需要扫描t1中每条记录的整个派生表。

你应该使用MySQL的EXPLAIN来查看确切的执行策略是什么,但我怀疑派生表是什么让你失望。

答案 1 :(得分:0)

正确的查询应该是:

SELECT
  t1.id,
  t1.t3_Id,
  MAX(t2.added) as last
FROM t1
  LEFT JOIN t2 on t1.t3_Id = t2.t3_Id
GROUP BY t2.t3_id
ORDER BY last;

这是因为临时表正在每条记录上生成。

答案 2 :(得分:0)

我认为您可以尝试在记录可用后订购所有内容。也许:

select * from (
select * from 
(select t3_id,max(t1_id) from t1 group by t3_id) as t1
left join (select t3_id,max(added) as last from t2 group by t3_id) as t2 
on t1.t3_id = t2.t3_id ) as xx
order by last