我有一个结构为 -
的表CREATE TABLE `cdr` (`id` bigint(20) NOT NULL AUTO_INCREMENT,
`dataPacketDownLink` bigint(20) DEFAULT NULL,
`dataPacketUpLink` bigint(20) DEFAULT NULL,
`dataPlanEndTime` datetime DEFAULT NULL,
`dataPlanStartTime` datetime DEFAULT NULL,
`dataVolumeDownLink` bigint(20) DEFAULT NULL,
`dataVolumeUpLink` bigint(20) DEFAULT NULL,
`dataplan` varchar(255) DEFAULT NULL,
`dataplanType` varchar(255) DEFAULT NULL,
`createdOn` datetime DEFAULT NULL,
`deviceName` varchar(500) DEFAULT NULL,
`duration` int(11) NOT NULL,
`effectiveDuration` int(11) NOT NULL,
`hour` int(11) DEFAULT NULL,
`eventDate` datetime DEFAULT NULL,
`msisdn` bigint(20) DEFAULT NULL,
`quarter` int(11) DEFAULT NULL,
`validDays` int(11) DEFAULT NULL,
`dataLeft` bigint(20) DEFAULT NULL,
`completedOn` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `msisdn_index` (`msisdn`),
KEY `eventdate_index` (`eventDate`)
) ENGINE=MyISAM AUTO_INCREMENT=55925171 DEFAULT CHARSET=latin1
现在,当我尝试编写此查询时,它从2000万条记录中花费了超过1分钟 -
select c.msisdn,sum(c.dataVolumeDownLink+c.dataVolumeUpLink) as datasum from cdr c where c.eventDate>=<date> group by c.msisdn order by datasum desc;
实际上,我有超过400万的记录。
解释计划 -
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE c ALL eventdate_index 20000420 Using where; Using temporary; Using filesort
我无法进行分区,请告诉我如何优化此查询。 谢谢。
答案 0 :(得分:1)
优化是一门艺术。
首先在eventDate上添加一个索引。这可能会让你非常接近,除非你试图寻找一个非常广泛的日期范围,你试图同时获得几乎所有的记录。
其他可能性可能包括在msisdn和eventDate上创建组合索引。索引中的顺序确实很重要,因此对msisdn进行索引然后eventDate与eventDate和msisdn上的索引不同。
然后继续使用分析仪查看哪些有效,哪些无效。