Mysql查询优化需要30秒以上

时间:2014-12-16 14:11:20

标签: mysql query-optimization

嗨朋友可以任何人帮我优化这个查询,需要30秒以上。 任何建议都受到热烈欢迎。

查询:

SELECT 
    CONCAT(CCD.CONTACT_FIRST_NAME, ' ', CCD.CONTACT_LAST_NAME) AS NAME,
    A.EMAIL_IDS,
    CCD.UNSUBSCRIBE,
    IFNULL(CSL.LOG_DATE, '') AS LOG_DATE,
    CSL.IP_ADDRESS,
    IF(CSL.BROWSER IS NULL, '', CSL.BROWSER) AS BROWSER,
    (CASE
        WHEN (UNSUBSCRIBE = 0 OR UNSUBSCRIBE IS NULL) THEN 'Opted In'
        ELSE (CASE
            WHEN (UNSUBSCRIBE = 1) THEN 'Opted Out'
            ELSE (CASE
                WHEN
                    ((UNSUBSCRIBE = 2 OR UNSUBSCRIBE = 3)
                        AND CCD.CONTACT_ID NOT IN (SELECT 
                            CONTACT_ID
                        FROM
                            CM_SUBSCRIPTION_MAIL_DATA
                        WHERE
                            IS_MAIL_SENT = 'Y'))
                THEN
                    'Opt-In Request not Sent'
                ELSE 'Opt-In Pending'
            END)
        END)
    END) AS CURR_SUB,
    (CASE
        WHEN (SUBSCRIBE_FROM = 0) THEN 'Opted In'
        ELSE (CASE
            WHEN (SUBSCRIBE_FROM = 1) THEN 'Opted Out'
            ELSE (CASE
                WHEN (SUBSCRIBE_FROM = 2 OR SUBSCRIBE_FROM = 3) THEN 'Opt-In Pending'
                ELSE ''
            END)
        END)
    END) AS SUB_FROM,
    SUBSCRIBE_FROM,
    (CASE
        WHEN (SUBSCRIBE_TO = 0) THEN 'Opted In'
        ELSE (CASE
            WHEN (SUBSCRIBE_TO = 1) THEN 'Opted Out'
            ELSE (CASE
                WHEN (SUBSCRIBE_TO = 2 OR SUBSCRIBE_TO = 3) THEN 'Opt-In Pending'
                ELSE ''
            END)
        END)
    END) AS SUB_TO,
    SUBSCRIBE_TO
FROM
    CM_CONTACT_DETAILS CCD
        LEFT JOIN
    ADDRESS A ON CCD.CONTACT_ID = A.FOREIGN_ID
        LEFT JOIN
    CM_SUBSCRIPTION_LOGS CSL ON CSL.CONTACT_ID = CCD.CONTACT_ID
WHERE
    1 = 1
GROUP BY CSL.LOG_DATE , CCD.CONTACT_ID
ORDER BY NAME DESC , LOG_DATE DESC
LIMIT 0 , 20

1 个答案:

答案 0 :(得分:0)

你的案例/什么时候可以简化,但我相信你的查询的杀手是未发送的选择加入请求的相关NOT IN SELECT条款。

我已根据联系人和邮件状态“Y”更改您的查询以对邮件表进行左连接。因此,这简化了您的情况,只需检查邮件表联系人ID的IS NULL。

你不能在性能方面做太多,因为你的Group by是来自不同表格中不会利用任何索引优化的列,那么所有按名称排序的都会让它更成为一个问题......但是每次执行左边连接的每个字段的相关子查询应该给予帮助。

SELECT 
      CONCAT(CCD.CONTACT_FIRST_NAME, ' ', CCD.CONTACT_LAST_NAME) AS NAME,
      A.EMAIL_IDS,
      CCD.UNSUBSCRIBE,
      IFNULL(CSL.LOG_DATE, '') AS LOG_DATE,
      CSL.IP_ADDRESS,
      IF(CSL.BROWSER IS NULL, '', CSL.BROWSER) AS BROWSER,
      CASE WHEN UNSUBSCRIBE = 0 OR UNSUBSCRIBE IS NULL THEN 'Opted In'
           WHEN UNSUBSCRIBE = 1 THEN 'Opted Out'
           WHEN UNSUBSCRIBE IN (2,3) AND SMD.CONTACT_ID IS NULL THEN 'Opt-In Request not Sent'
           ELSE 'Opt-In Pending' END AS CURR_SUB,
      CASE WHEN SUBSCRIBE_FROM = 0 THEN 'Opted In'
           WHEN SUBSCRIBE_FROM = 1 THEN 'Opted Out'
           WHEN SUBSCRIBE_FROM = 2 OR SUBSCRIBE_FROM = 3 THEN 'Opt-In Pending'
           ELSE '' END AS SUB_FROM,
      SUBSCRIBE_FROM,
      CASE WHEN SUBSCRIBE_TO = 0 THEN 'Opted In'
           WHEN SUBSCRIBE_TO = 1 THEN 'Opted Out'
           WHEN SUBSCRIBE_TO = 2 OR SUBSCRIBE_TO = 3 THEN 'Opt-In Pending'
           ELSE '' END AS SUB_TO,
      SUBSCRIBE_TO
   FROM
      CM_CONTACT_DETAILS CCD
         LEFT JOIN ADDRESS A 
            ON CCD.CONTACT_ID = A.FOREIGN_ID
         LEFT JOIN CM_SUBSCRIPTION_LOGS CSL 
            ON CSL.CONTACT_ID = CCD.CONTACT_ID
         LEFT JOIN CM_SUBSCRIPTION_MAIL_DATA SMD
            ON CCD.CONTACT_ID = SMD.CONTACT_ID
            AND IS_MAIL_SENT = 'Y'
   WHERE
      1 = 1
   GROUP BY 
      CSL.LOG_DATE, 
      CCD.CONTACT_ID
   ORDER BY 
      NAME DESC, 
      LOG_DATE DESC
   LIMIT 
      0, 20