前言:本案例是前段时间某投票活动的优化,在阿里云监控上发现RDS CPU使用率竟然超过60%,按照常规套路,首先第一个想到的就是没有使用合适的索引。
说时迟,那时快,通过show processlist捕捉到大量的线程同时在执行相同的sql,我们来看下
CREATE TABLE `xxx` (`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',`group_id` int(11) unsigned DEFAULT '0' COMMENT '分组id',`vote_id` int(11) unsigned NOT NULL COMMENT '投票id',`id_num` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT '编号',`title` varchar(25) CHARACTER SET utf8mb4 NOT NULL COMMENT '标题',`group_img` varchar(100) DEFAULT NULL COMMENT '分组图片',`list_img` varchar(100) DEFAULT NULL COMMENT '列表图片',`first_banner` varchar(100) DEFAULT NULL COMMENT '第一张banner图',`real_num` int(11) unsigned DEFAULT '0' COMMENT '真实的票数(点赞数)',`add_num` int(11) DEFAULT '0' COMMENT '运营人员增减的票数(点赞数),允许为负,前后台显示real和add之和',`real_cai_num` int(11) unsigned DEFAULT '0' COMMENT '真实点踩数',`add_cai_num` int(11) DEFAULT '0' COMMENT '运营人员增减的点踩数,允许为负,前后台显示real和add之和',`_create` int(11) unsigned NOT NULL COMMENT '创建时间',`_update` int(11) unsigned DEFAULT NULL COMMENT '修改时间',`create_user` varchar(32) NOT NULL COMMENT '创建人,有可能是用户的openid',`update_user` int(11) unsigned DEFAULT NULL COMMENT '修改人',PRIMARY KEY (`id`),KEY `index_group` (`group_id`) USING BTREE,KEY `index_vote_id` (`vote_id`,`status`) USING BTREE) ENGINE=InnoDB AUTO_INCREMENT=2084 DEFAULT CHARSET=utf8 COMMENSELECT `vote_id`,`is_local`,`id_num`,`id`,`title`,`declare`,`remark`,`video`,`link_video`,`video_pic`, (real_num+add_num) as vote_num, (real_cai_num+add_cai_num) as cai_num FROM `vote_candidate` WHERE (`status`=1) AND (`vote_id`='172') AND (`id_num`='38') LIMIT 1
为了安全,去掉了部分字段跟注释,咋一看,就知道这个又是投票相关的SQL,当时心里妈卖批,开发狗又不用redis来做计数器,但是又没办法,项目都上线了,只能看着优化优化了,分析了一下,这个sql其实不难,添加一个索引即可以达到优化的效果。
总记录数:1830区分度:status:3vote_id:59id_num:237create index idx_idn_voteid_status on vote_candidate(id_num,vote_id,status);
根据索引最左匹配原则,创建多列索引如上,再来看执行计划:
{"query_block": {"select_id": 1,"table": {"table_name": "vote_candidate","access_type": "ref","possible_keys": ["index_vote_id","idx_idn_voteid_status"],"key": "idx_idn_voteid_status","used_key_parts": ["id_num","vote_id","status"],"key_length": "8","ref": ["const","const","const"],"rows": 1,"filtered": 100}}}
看到条件都已匹配到,CPU使用率马上就降到5%以下了,看来效果还是不错的。
