使用mysql的innodb引擎执行count查询时发现速度很慢。一个将近800万条数据的表执行count(*)差不多40多秒时间。使用count(1)和count(主键)也基本差不多。
表结构如下:执行count(*)1SELECT COUNT(*) FROM sds_third_match_info;
耗时:57.733sec执行count(1)1SELECT COUNT(1) FROM sds_third_match_info;
耗时:55.428sec执行count(主键)1SELECT COUNT(id) FROM sds_third_match_info;
耗时:56.209sec
原因分析:
InnoDB的索引是B+Tree。
对主键索引来说:它只有在叶子节点上存储数据,它的key是主键,并且value为整条数据。
对辅助索引来说:key为建索引的列,value为主键。
这给我们两个信息:根据主键会查到整条数据
根据辅助索引只能查到主键,然后必须通过主键再查到剩余信息。
所以如果要优化count(*)操作的话,我们需要找一个短小的列,为它建立辅助索引。
我们在sport_data_type上建立一个普通索引1ALTER TABLE sds_third_match_info ADD INDEX idx_sporttype_stmi(sport_data_type);
然后根据索引列做count1SELECT COUNT(sport_data_type) FROM sds_third_match_info t;
现在耗时:2.649sec
如果在where条件中根据索引列过滤:1SELECT COUNT(sport_data_type) FROM sds_third_match_info t WHERE sport_data_type=1;
耗时:0.052sec
看看执行计划:
EXPLAIN SELECT COUNT(sport_data_type) FROM sds_third_match_info t WHERE sport_data_type=1;
如果是count(*)则执行计划是全表扫描。