MySql索引和查询优化以及最短的执行时间

时间:2016-06-01 08:34:24

标签: mysql optimization

目前我正在处理 600K 周围的记录,下面的查询需要 6.5秒的时间才能获取结果。

有人可以帮助我将执行时间缩短到2-3秒吗?

QUERY 1:

SELECT  DATE_FORMAT(`LS_CHG_DTE_OCR`, '%Y-%b') AS fmt_date, SUM(connects) AS connects,
        SUM(disconnects) AS disconnects, ROUND(SUM(REV),0) AS REV
    FROM  
      ( SELECT  LS_CHG_DTE_OCR, 
                IF(`TYPE`='Connect',COUNT(DISTINCT ORDER_NO_OHI), 0) AS connects,
                IF(`TYPE`='Disconnect',COUNT(DISTINCT ORDER_NO_OHI), 0) AS disconnects,
                IF(`TYPE`='Upgrade',COUNT(DISTINCT ORDER_NO_OHI), 0) AS Upgrades,
                IF(`TYPE`='Downgrades',COUNT(DISTINCT ORDER_NO_OHI), 0) AS Downgrades,
                SUM(IF(`TYPE`='Connect',REV,0)) AS REV
            FROM  hsd_26_05_2016
            WHERE  LS_CHG_DTE_OCR!=''
            GROUP BY  LS_CHG_DTE_OCR,TYPE 
      ) AS a
    GROUP BY  YEAR(LS_CHG_DTE_OCR), MONTH(LS_CHG_DTE_OCR)
    ORDER BY  LS_CHG_DTE_OCR ASC;

QUERY 2:

 CREATE TABLE `hsd_26_05_2016` (
      `id` int(20) NOT NULL AUTO_INCREMENT,
      `SYS_OCR` varchar(255) DEFAULT NULL,
      `PRIN_OCR` varchar(255) DEFAULT NULL,
      `ORDER_NO_OHI` varchar(255) NOT NULL,
      `SUB_ACCT_NO_OHI` varchar(255) DEFAULT NULL,
      `SERV_CDE_OHI` varchar(255) DEFAULT NULL,
      `DSC_CDE_OHI` varchar(255) DEFAULT NULL,
      `LS_CHG_DTE_OCR` date NOT NULL,
      `SALESREP_OCR` varchar(255) DEFAULT NULL,
      `CHANNEL` varchar(255) DEFAULT NULL,
      `CUST_TYPE` varchar(255) DEFAULT NULL,
      `LINE_BUS` varchar(255) DEFAULT NULL,
      `ADDR1_HSE` varchar(255) DEFAULT NULL,
      `RES_CITY_HSE` varchar(255) DEFAULT NULL,
      `RES_STATE_HSE` varchar(255) DEFAULT NULL,
      `POSTAL_CDE_HSE` varchar(255) DEFAULT NULL,
      `ZIP` varchar(10) DEFAULT NULL,
      `COUNT_SUBS` double DEFAULT NULL,
      `REV` double NOT NULL,
      `TYPE` varchar(255) NOT NULL,
      `SERVICECATEGORY` varchar(200) DEFAULT NULL,
      `lat` varchar(100) DEFAULT NULL,
      `long` varchar(100) DEFAULT NULL,
      PRIMARY KEY (`id`,`LS_CHG_DTE_OCR`,`TYPE`,`ORDER_NO_OHI`),
      KEY `idx2` (`CHANNEL`,`CUST_TYPE`,`LINE_BUS`),
      KEY `idx1` (`RES_STATE_HSE`,`RES_CITY_HSE`,`ZIP`)
    ) ENGINE=InnoDB AUTO_INCREMENT=1134054 DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC

如果索引中有任何建议,请建议我。任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:1)

按照日期和类型首先“计算不同”,然后将这些数量相加?这看起来“错了”。如果你想要一个月的“唯一身份”,你就无法通过对这几天的总结得到它。

对数据进行2次传递;我认为一个就足够了。

考虑GROUP BY LEFT(LS_CHG_DTE_OCR, 7)

当该值不可用时,请勿使用ORDER BY LS_CHG_DTE_OCR ASC。而是使用与GROUP BY中相同的值。

如果不是DISTINCT,那么构建“摘要表”以提高效率会很容易。但是,this blog解释了如何卷起“唯一身份”,尽管误差通常为1%。这还不错吗?