我试着解释一个非常高的水平
我有两个复杂的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
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
。
我想了解原因
这么大爆炸的原因是什么?
注意:
每个表上所有已使用的列都已编制索引 例如:
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)
答案 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