非常非常慢的查询

时间:2013-09-11 17:55:46

标签: mysql sql

我有这个问题:

SELECT 
    a.id,
    a.name, 
    count(b.id),
    count(c.id), 
    count(e.id), 
    count(f.id)
FROM 
    organizations a
LEFT JOIN vessels b ON a.id = b.organization_id
LEFT JOIN licences c ON a.id = c.organization_id
LEFT JOIN fleets e ON a.id = e.organization_id
LEFT JOIN users f ON a.id = f.organization_id
GROUP BY a.id;

在所有表中都有一个正确的索引(主索引上的organization_id ),organizations中有大约80行,fleets中有400行, vessels中的2900,licences中的3000和users中的10

此查询甚至没有成功,它仍然停留在copying to temp table

我应该如何重新使用此查询以使其正常工作?

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  a   index       PRIMARY 4       1   
1   SIMPLE  b   ref organisation_id organisation_id 4   fuel.a.id   70  Using index
1   SIMPLE  c   ref organisation_id organisation_id 4   fuel.a.id   15  Using index
1   SIMPLE  e   ref organisation_id organisation_id 4   fuel.a.id   5   
1   SIMPLE  f   ref organization_id organization_id 5   fuel.a.id   1   Using index

1 个答案:

答案 0 :(得分:8)

你的联接不依赖于彼此,这就是临时表爆炸的原因。

一个简单的解决方法是:

SELECT 
    a.id,
    a.name, 
    (select count(*) from vessels b where a.id = b.organization_id group by b.organization_id),
    (select count(*) from licenses b where a.id = b.organization_id group by b.organization_id),
    (select count(*) from fleets b where a.id = b.organization_id group by b.organization_id),
    (select count(*) from users b where a.id = b.organization_id group by b.organization_id),
FROM 
    organizations a

如果你这样做会快得多:

SELECT 
    a.id,
    a.name,
    v.total,
    w.total,        
    x.total,
    y.total
FROM 
    organizations a
LEFT JOIN (select b.organizantion_id, count(*) total from vessels b group by b.organization_id) v on v.organization_id=a.id
LEFT JOIN (select b.organizantion_id, count(*) total from licenses b group by b.organization_id) w on w.organization_id=a.id
LEFT JOIN (select b.organizantion_id, count(*) total from fleets b group by b.organization_id) x on x.organization_id=a.id
LEFT JOIN (select b.organizantion_id, count(*) total from users b group by b.organization_id) y on y.organization_id=a.id