2013-09-11 3 views
3

У меня есть этот запрос:Очень, очень медленный запрос

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), есть около 80 строк в organizations, 400 в fleets, 2900 в vessels, 3000 в licences и 10 в users

Этот запрос даже не удастся, он застрял на 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 
+3

Что делает [ 'EXPLAIN'] (HTTP: // dev.mysql.com/doc/refman/5.0/en/explain.html) скажите? – h2ooooooo

+0

Сначала вы можете использовать объяснение, чтобы проверить, что делает это медленным, во-вторых, вы делаете много объединений, третий смотрите на индексы, которые у вас есть, или вы должны их создать. –

+0

является 'organization_id' NULLABLE? – Chris

ответ

8

Ваши соединения не зависят друг от друга, поэтому таблицы temp взрываются.

Простое исправление сделать:

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 
+0

Я перестроил ваш запрос к этому: http: // pastebin .com/ueMpa7kt, который работает очень быстро! Благодаря! ++ для вас! – Sander

Смежные вопросы