我正在处理一个40K行的mysql表。表indexed.c当前执行时间大约为2秒。有人指导我如何更好地优化此查询和表格?以及如何在...中使用;使用临时;使用filesort" ??。任何帮助表示赞赏。
与以下情况一起使用...
提前致谢
SELECT DATE_FORMAT(`LS_CHG_DTE_OCR`, '%Y-%b') AS fmt_date,
SUM(IF(`TYPE`='Connect',COUNT_SUBS,0)) AS connects,
SUM(IF(`TYPE`='Disconnect',COUNT_SUBS,0)) AS disconnects,
SUM(IF(`TYPE`='Connect',ROUND(REV,2),0)) AS REV,
SUM(IF(`TYPE`='Upgrade',COUNT_SUBS,0)) AS upgrades,
SUM(IF(`TYPE`='Downgrade',COUNT_SUBS,0)) AS downgrades,
SUM(IF(`TYPE`='Upgrade',ROUND(REV,2),0)) AS upgradeRev FROM `hsd`
WHERE LS_CHG_DTE_OCR!='' GROUP BY MONTH(LS_CHG_DTE_OCR) ORDER BY LS_CHG_DTE_OCR ASC
CREATE TABLE `hsd` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`SYS_OCR` varchar(255) DEFAULT NULL,
`PRIN_OCR` varchar(255) DEFAULT NULL,
`SERV_CDE_OHI` varchar(255) DEFAULT NULL,
`DSC_CDE_OHI` varchar(255) DEFAULT NULL,
`LS_CHG_DTE_OCR` datetime DEFAULT 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(100) DEFAULT NULL,
`COUNT_SUBS` double DEFAULT NULL,
`REV` double DEFAULT NULL,
`TYPE` varchar(255) DEFAULT NULL,
`lat` varchar(100) DEFAULT NULL,
`long` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx` (`LS_CHG_DTE_OCR`,`CHANNEL`,`CUST_TYPE`,`LINE_BUS`,`RES_CITY_HSE`,`RES_STATE_HSE`,`POSTAL_CDE_HSE`,`ZIP`,`COUNT_SUBS`,`TYPE`)
) ENGINE=InnoDB AUTO_INCREMENT=402342 DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
Using where; Using temporary; Using filesort[enter image description here][1]
答案 0 :(得分:0)
您申请的唯一条件是LS_CHG_DTE_OCR!=“”。除此之外,由于聚合,您正在进行全表扫描。索引方面,你在这里做不了多少。
我遇到了同样的问题。我已经完全优化了我的查询(我有连接和更多条件)但是表不断增长并且查询时间也是如此。最后,我决定将数据镜像到ElasticSearch。在我的情况下,它将查询时间减少到大约1/20到1/100(对于不同的查询)。
答案 1 :(得分:0)
SELECT
唯一可能的索引是INDEX(LS_CHG_DTE_OCR)
。但它不太可能被使用。
WHERE
- 如果有''
个值的批次,则可以使用索引 进行过滤。GROUP BY MONTH(...)
- 您可能会在同一个月内折叠多年。优化程序无法说明,因此它会使用索引。ORDER BY LS_CHG_DTE_OCR
- 这是在 GROUP BY
之后完成的。在收集数据之前无法执行ORDER BY
- 对于任何索引来说都太迟了。但是,如果将多年折叠在一起,您可能会得到一些奇怪的结果。通过使ORDER BY
与GROUP BY
相同来解决此问题。这也可以防止由GROUP BY
和ORDER BY
造成的额外排序。是的,如果您添加的idx
all SELECT
中的列,那么它就是"覆盖索引"。但由于上述评论,它不会给任何人带来帮助。 "使用索引"不是很有帮助。
GROUP BY LS_CHG_DTE_OCR/RES_STATE_HSE
- 呃?将DATETIME
除以VARCHAR
?这听起来像是一场灾难。
随着时间的推移,这张桌子会变得更大,对吗?考虑使用month
构建和维护摘要表作为PRIMARY KEY
。