我继承了一个客户端的应用程序,并且一直在处理以下查询,该查询需要187秒并搜索304M表行以发回444个结果行。
我是否有权想要摆脱子选择并用连接替换它们?我找不到正确的方法。任何优化此查询的帮助都将非常受欢迎。感谢...
SELECT Business.name, Business.primary_city, Count(click.id) as clicks, Count(DISTINCT email_leads.parent_message_id) as tot_email_leads, Count(bc.business_id) as county_no, Count(br.business_id) as region_no, count(reveals.id) as reveals_no
FROM businesses as Business
LEFT JOIN business_clickthroughs as click ON ( Business.id = click.business_id AND (click.created BETWEEN '2014-04-01 00:00:00' and '2014-04-30 23:59:59'))
LEFT JOIN users as U ON Business.id = U.business_id
LEFT JOIN messages as email_leads ON (U.id = email_leads.from_to AND (email_leads.parent_message_id is null OR email_leads.parent_message_id = email_leads.id ) AND (email_leads.created BETWEEN '2014-04-01 00:00:00' and '2014-04-30 23:59:59'))
LEFT JOIN business_counties as bc ON Business.id = bc.business_id
LEFT JOIN businesses_business_types as bt ON Business.id = bt.business_id
LEFT JOIN business_reveals as reveals ON (reveals.business_id = Business.id AND (reveals.created BETWEEN '2014-04-01 00:00:00' and '2014-04-30 23:59:59'))
LEFT JOIN business_regions as br ON Business.id = br.business_id
WHERE 1=1
Group By Business.id;
答案 0 :(得分:0)
从您正在编写的查询来看,子选择可能是正确的方法。您没有显示实际的原始查询,因此这只是猜测。
您的查询正在加入数据,这些数据很容易就是单独的维度 - 用户,消息,县,“揭示”(无论是什么)。然后,连接将为每个业务生成这些维度的笛卡尔积,进一步放大数据并减慢查询速度。
而且,如果你的较大的表有3亿多行,那么300秒来总结 all 8个左右表中的数据似乎并不合理。您的查询没有任何过滤数据的where
条件。 join
s都是left join
s,这会减少过滤。
如果性能问题,请询问其他问题。包括实际查询,查询的explain
计划以及表的布局(尤其是索引结构)。