您好,登录后才能下订单哦!
请求超时!
请点击 重新获取二维码有一个业务是查询最新审核的5条数据
SELECT `id`, `title` FROM `th_content` WHERE `audit_time` < 1541984478 AND `status` = 'ONLINE' ORDER BY `audit_time` DESC, `id` DESC LIMIT 5;
查看当时的监控情况 cpu 使用率是超过了100%,show processlist
看到很多类似的查询都是处于create sort index
的状态。
查看该表的结构
CREATE TABLE `th_content` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `title` varchar(500) CHARACTER SET utf8 NOT NULL DEFAULT '' COMMENT '内容标题', `content` mediumtext CHARACTER SET utf8 NOT NULL COMMENT '正文内容', `audit_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '审核时间', `last_edit_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最近编辑时间', `status` enum('CREATED','CHECKING','IGNORED','ONLINE','OFFLINE') CHARACTER SET utf8 NOT NULL DEFAULT 'CREATED' COMMENT '资讯状态', PRIMARY KEY (`id`), KEY `idx_at_let` (`audit_time`,`last_edit_time`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
索引有一个audit_time
在左边的联合索引,没有关于status
的索引。
分析上面的sql执行的逻辑:
最后因为数据量很大,虽然只取5行,但是按照我们刚刚举的极端例子,实际查询了100万行数据,而且最后还在内存中进行了50万行数据库的内存排序。
所以是非常低效的。
画了一个示意图,说明第一步的查询过程,粉红色部分表示最后需要回表查询的数据行。
图中我按照索引存储规律来YY伪造填充了一些数据,如有不对请留言指出。希望通过这张图大家能够看到联合索引存储的方式和索引查询的方式
改进思路 1
范围查找向来不太好使用好索引的,如果我们增加一个audit_time
, status
的联合索引,会有哪些改进呢?
ALTER TABLE `th_content` ADD INDEX `idx_audit_status` (`audit_time`, `status`);
mysql> explain select `id`, `title` from `th_content` where `audit_time` < 1541984478 and `status` = 'ONLINE' order by `audit_time` desc, `id` desc limit 5; +----+-------------+------------+-------+------------------------------------------+------------------+---------+------+--------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------+-------+------------------------------------------+------------------+---------+------+--------+-------------+ | 1 | SIMPLE | th_content | range | idx_at_ft_pt_let,idx_audit_status | idx_audit_status | 4 | NULL | 209754 | Using where | +----+-------------+------------+-------+------------------------------------------+------------------+---------+------+--------+-------------+
细节:因为audit_time
是一个范围查找,所以第二列的索引用不上了,只能用到audit_time
,所以key_len
是4。而下面思路2中,还是这两个字段key_len
则是5。
还是分析下在添加了该索引之后的执行过程:
audit_time
最大的一行的联合索引< audit_time
是一个范围查找,而第二列索引的值是分散的。所以需要依次往前查找,匹配出满足条件(status
='ONLINE')的索引行,直到取到第5行为止。在上面的示意图中,粉红色标识满足第一列索引要求的行,依次向前查询,本个叶子节点上筛选到了3条记录,然后需要继续向左,到前一个叶子节点继续查询。直到找到5条满足记录的行,最后回表。
改进之处
因为在索引里面有status
的值,所以在筛选满足status
='ONLINE'行的时候,就不用回表查询了。在回表的时候只有5行数据的查询了,在iops
上会大大减少。
该索引的弊端
如果idx_audit_status
里扫描5行都是status
是ONLINE
,那么只需扫描5行;
如果idx_audit_status
里扫描前100万行中,只有4行status
是ONLINE
,则需要扫描100万零1行,才能得到需要的5行记录。索引需要扫描的行数不确定。
改进思路 2
ALTER TABLE `th_content` DROP INDEX `idx_audit_status`; ALTER TABLE `th_content` ADD INDEX `idx_status_audit` (`status`, `audit_time`);
这样不管是排序还是回表都毫无压力啦。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对亿速云的支持。如果你想了解更多相关内容请查看下面相关链接
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
代做工资流水公司岳阳房贷收入证明打印菏泽代做银行流水账单济南日常消费流水宿迁流水账单制作九江薪资银行流水价格潮州收入证明图片台州查询背调流水威海制作贷款流水泰安银行流水单公司兰州薪资银行流水开具包头贷款银行流水开具济南代办流水银川银行对公流水公司岳阳消费贷流水查询临沂打签证银行流水柳州入职银行流水烟台对公流水开具青岛企业对公流水制作重庆办理入职银行流水宿迁办银行流水广州自存流水模板入职流水样本太原消费贷流水咸阳打入职流水武汉制作流水单沧州银行流水修改查询无锡日常消费流水公司宁德在职证明打印绵阳对公流水多少钱汕头查询银行流水账单香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声卫健委通报少年有偿捐血浆16次猝死汪小菲曝离婚始末何赛飞追着代拍打雅江山火三名扑火人员牺牲系谣言男子被猫抓伤后确诊“猫抓病”周杰伦一审败诉网易中国拥有亿元资产的家庭达13.3万户315晚会后胖东来又人满为患了高校汽车撞人致3死16伤 司机系学生张家界的山上“长”满了韩国人?张立群任西安交通大学校长手机成瘾是影响睡眠质量重要因素网友洛杉矶偶遇贾玲“重生之我在北大当嫡校长”单亲妈妈陷入热恋 14岁儿子报警倪萍分享减重40斤方法杨倩无缘巴黎奥运考生莫言也上北大硕士复试名单了许家印被限制高消费奥巴马现身唐宁街 黑色着装引猜测专访95后高颜值猪保姆男孩8年未见母亲被告知被遗忘七年后宇文玥被薅头发捞上岸郑州一火锅店爆改成麻辣烫店西双版纳热带植物园回应蜉蝣大爆发沉迷短剧的人就像掉进了杀猪盘当地回应沈阳致3死车祸车主疑毒驾开除党籍5年后 原水城县长再被查凯特王妃现身!外出购物视频曝光初中生遭15人围殴自卫刺伤3人判无罪事业单位女子向同事水杯投不明物质男子被流浪猫绊倒 投喂者赔24万外国人感慨凌晨的中国很安全路边卖淀粉肠阿姨主动出示声明书胖东来员工每周单休无小长假王树国卸任西安交大校长 师生送别小米汽车超级工厂正式揭幕黑马情侣提车了妈妈回应孩子在校撞护栏坠楼校方回应护栏损坏小学生课间坠楼房客欠租失踪 房东直发愁专家建议不必谈骨泥色变老人退休金被冒领16年 金额超20万西藏招商引资投资者子女可当地高考特朗普无法缴纳4.54亿美元罚金浙江一高校内汽车冲撞行人 多人受伤