前言:本案例是前段时间某投票活动的优化,在阿里云监控上发现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 COMMEN
SELECT `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:3
vote_id:59
id_num:237
create 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%以下了,看来效果还是不错的。