简体   繁体   English

mysql查询需要3个小时来运行和处理

[英]mysql query takes 3 hours to run and process

I have a query that is ran on a cron job late at night.我有一个在深夜执行 cron 作业的查询。 This query is then processed through a generator as it has to populate another database and I make some additional processes and checks before it is sent to the other DB.然后通过生成器处理此查询,因为它必须填充另一个数据库,并且在将其发送到另一个数据库之前我会进行一些额外的处理和检查。

I am wondering is there anyway for me to speed up this query and hopefully keep it as a single query.我想知道无论如何我是否可以加快此查询并希望将其保留为单个查询。 Or will I be forced to create other queries and join the data within PHP?还是我会被迫创建其他查询并在 PHP 中加入数据? This queries the main mautic database.这会查询主 mautic 数据库。

SELECT  c.id as "campaign_id",
        c.created_by_user,
        c.name,
        c.date_added,
        c.date_modified,
        (SELECT DISTINCT COUNT(cl.lead_id)) as number_of_leads,
        GROUP_CONCAT(lt.tag) as tags,
        cat.title as category_name,
        GROUP_CONCAT(ll.name) as segment_name,
        GROUP_CONCAT(emails.name) as email_name,
        CASE WHEN c.is_published = 1 THEN "Yes" ELSE "No" END AS "published",
        CASE WHEN c.publish_down > now() THEN "Yes" 
             WHEN c.publish_down > now() AND c.is_published = 0 THEN "Yes" 
             ELSE "No" END AS "expired"
FROM campaigns c 
    LEFT JOIN campaign_leads cl ON cl.campaign_id = c.id
    LEFT JOIN lead_tags_xref ltx on cl.lead_id = ltx.lead_id 
    LEFT JOIN lead_tags lt on ltx.tag_id = lt.id 
    LEFT JOIN categories cat on c.category_id = cat.id 
    LEFT JOIN lead_lists_leads llist on cl.lead_id = llist.lead_id 
    LEFT JOIN lead_lists ll on llist.leadlist_id = ll.id 
    LEFT JOIN email_list_xref el on ll.id = el.leadlist_id 
    LEFT JOIN emails on el.email_id = emails.id 
GROUP BY c.id;

Here is a image of the explain https://prnt.sc/qQtUaLK3FIpQ这是解释https://prnt.sc/qQtUaLK3FIpQ的图像

Definitions Campaign Table: https://prnt.sc/6JXRGyMsWpcd定义活动表: https ://prnt.sc/6JXRGyMsWpcd

Campaign_leads table https://prnt.sc/pOq0_SxW2spe Campaign_leads 表https://prnt.sc/pOq0_SxW2spe

lead_tags_xref table https://prnt.sc/oKYn92O82gHL Lead_tags_xref 表https://prnt.sc/oKYn92O82gHL

lead_tags table https://prnt.sc/ImH81ECF6Ly1铅标签表https://prnt.sc/ImH81ECF6Ly1

categories table https://prnt.sc/azQj_Xwq3dw9类别表https://prnt.sc/azQj_Xwq3dw9

lead_lists_lead table https://prnt.sc/x5C5fiBFP2N7 Lead_lists_lead 表https://prnt.sc/x5C5fiBFP2N7

lead_lists table https://prnt.sc/bltkM0f3XeaH Lead_lists 表https://prnt.sc/bltkM0f3XeaH

email_list_xref table https://prnt.sc/kXABVJSYWEUI email_list_xref 表https://prnt.sc/kXABVJSYWEUI

emails table https://prnt.sc/7fZcBir1a6QT电子邮件表https://prnt.sc/7fZcBir1a6QT

I am only expected 871 rows to be completed, I have identified that the joins can be very large, in the tens of thousands.我只希望完成 871 行,我已经确定连接可能非常大,数以万计。

Seems you have an useless select DISTINTC .. could you are looking for a conut(distinct .. )似乎您有一个无用的选择 DISTINTC .. 您是否正在寻找一个 conut(distinct .. )
In this way you can avoid nested select for each rows in main select ..通过这种方式,您可以避免主选择中每一行的嵌套选择..

SELECT  c.id as "campaign_id",
        c.created_by_user,
        c.name,
        c.date_added,
        c.date_modified,
        COUNT(DISTINCT cl.lead_id) as number_of_leads,
        GROUP_CONCAT(lt.tag) as tags,
        cat.title as category_name,
        GROUP_CONCAT(ll.name) as segment_name,
        GROUP_CONCAT(emails.name) as email_name,
        CASE WHEN c.is_published = 1 THEN "Yes" ELSE "No" END AS "published",
        CASE WHEN c.publish_down > now() THEN "Yes" 
             WHEN c.publish_down > now() AND c.is_published = 0 THEN "Yes" 
             ELSE "No" END AS "expired"
FROM campaigns c 
    LEFT JOIN campaign_leads cl ON cl.campaign_id = c.id
    LEFT JOIN lead_tags_xref ltx on cl.lead_id = ltx.lead_id 
    LEFT JOIN lead_tags lt on ltx.tag_id = lt.id 
    LEFT JOIN categories cat on c.category_id = cat.id 
    LEFT JOIN lead_lists_leads llist on cl.lead_id = llist.lead_id 
    LEFT JOIN lead_lists ll on llist.leadlist_id = ll.id 
    LEFT JOIN email_list_xref el on ll.id = el.leadlist_id 
    LEFT JOIN emails on el.email_id = emails.id 
GROUP BY c.id;

anyway be sure you have a proper composite index on无论如何要确保你有一个适当的复合索引

table campaign_leads columns campaign_id, lead_id
table lead_tags_xref columns lead_id, tag_id
table lead_lists_leads columns lead_id, leadlist_id
table email_list_xref columns leadlist_id, email_id 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM