优化MySQL的自联接
问题描述:
我有自连接查询的表400万个记录....我们如何优化查询...查询与最大日期读取行优化MySQL的自联接
SELECT DISTINCT d1.C1 AS c1, d1.C2 AS c2, d1.C3 AS c3,
d1.datedm_id AS c4 FROM TABLEA d1 LEFT OUTER JOIN TABLEA d2
ON (d1.C1 = d2.C1 AND d1.C2 = d2.C2 AND d1.datedm_id < d2.datedm_id)
WHERE d2.C1 IS NULL AND d2.C2 IS NULL
目前该查询时间很长时间来执行
EXPLAIN显示以下
d1 4051368 Using index; Using temporary
d2 1 Using where; Using index; Not exists; Distinct
答
优化这个查询,在tableA(C1, C2, datedm_id)
建立索引。
你可以把它改写为:
SELECT d1.C1 AS c1, d1.C2 AS c2, d1.C3 AS c3, d1.datedm_id AS c4
FROM TABLEA d1
WHERE not exists (select 1
from TABLEA d2
where d1.C1 = d2.C1 AND d1.C2 = d2.C2 AND d1.datedm_id < d2.datedm_id
);
这个版本一定要使用索引。第一个版本应该,但不一定在所有情况下。
答
试试这个:
select d1.C1 AS c1, d1.C2 AS c2, d1.C3 AS c3,
d1.datedm_id AS c4 FROM TABLEA d1
where not exists(
select 'nextdatedm'
from TABLEA d2
where d1.C1 = d2.C1 AND d1.C2 = d2.C2 AND d1.datedm_id < d2.datedm_id
)
我已经更换了你LEFT OUTER JOIN与EXISTS功能(在这种解决方案我会在那里不存在另一行与datedm更年轻的只有TABLEA)。
通过这种方式,您可以删除DISTINCT功能。
要完成您的任务,您可以添加一些关于比较字段的索引
是C1和C2索引的吗? –
你有没有试过解释?此外,DISTINCT可能与GROUP BY不一样,但在很多情况下它会产生相同的结果,并且可能会更快。 +如果可能,请避免使用外部连接并使用内部连接(除了您发布的内容外,不知道任何内容) – griffin
在SELECT之前添加'EXPLAIN EXTENDED'并查看它显示的内容?你在桌上有什么索引? –