首页
题库
公司真题
专项练习
面试题库
在线编程
面试
面试经验
AI 模拟面试
简历
求职
学习
基础学习课
实战项目课
求职辅导课
专栏&文章
竞赛
搜索
我要招人
发布职位
发布职位、邀约牛人
更多企业解决方案
AI面试、笔试、校招、雇品
HR免费试用AI面试
最新面试提效必备
登录
/
注册
我叫呀哈哈
武汉大学 Java
关注
已关注
取消关注
#牛客网博客#
@我叫呀哈哈:
从Mysql不走索引看InnoDB的索引原理
有索引的情况下,Mysql还是扫表,怎么回事 这两天碰到一个这个问题:在where语句中有一个字段可以走二级索引去范围查的情况下,发现mysql并没有走索引,而是扫表。不知道大家有没有遇到过这个问题。 为什么mysql在明明有索引的情况下却选择不走索引,而选择扫表呢?今天我们从InnoDB的索引原理讲一下为什么会出现这种现象。 InnoDB索引原理 InnoDB对于PK的索引策略和二级索引的策略是不一样的。 部分知识来自于《高性能MySQL》,以及我自己的理解,本人没有看过源码,所以大家对内容要自行甄别对错,自己思考,不要以我为准 数据结构 InnoDB的索引数据结构是B树,更准确的说是B+树。为什么是B+树呢?因为B+树非叶子节点不带数据,所以存储索引数据可以使用更少的磁盘存储空间,那么在PageCache读盘的时候,预读可以一次读取更多的索引数据,从而使用更少的磁盘IO就可以查询到更多的索引数据,这样就可以更快的定位到数据位置。 聚集索引 一张表只能有唯一的聚集索引。一般PK上的索引会自动被设置为聚集索引(但是你也可以先创建聚集索引,再创建PK,大多数情况下,PK索引就是聚集索引)。之所以叫聚集索引,是因为所有叶子节点上的记录都紧凑的按主键顺序存储在磁盘上。由于这个特点,使用主键自增会获得很好的写性能,因为是顺序写。 非聚集索引 二级索引和PK索引不一样,虽然数据结构也是B+树,但是叶子节点上的数据记录的是PK的值,而不是实际的数据,所以在使用二级索引查找到的实际是二级索引对应的PK索引。 这样会导致一个问题,就是对于二级索引上的范围查找,会导致大量的随机读IO。因为首先根据二级索引查找到的是一批离散的PK,然后再根据这些PK去查找记录,这时候会发生随机读IO,并且还带来了logn的额外查询时间。 覆盖索引 上面说到二级索引范围查找带来的随机IO现象,再有一种情况下不会发生,那就是SELECT的字段只有PK和二级索引的列,由于二级索引的叶子节点上保存的就是PK数据,并且二级索引中就保存了列的值,所以这时候不需要再回到PK索引上查找。 所以,如果我们SELECT中的列都有对应的索引存在的话,那么会提升查找效率,因为不需要去真正的记录里面去查找数据,只用在索引数据里面查找就行了。 这种索引称为覆盖索引。 回答问题 好了,对索引原理有一个大致的了解。 那么为什么有时候,where语句里面明明有索引可走的情况下,mysql会选择扫表呢?原因就是扫表是顺序IO,而二级索引是先查找PK,然后再在PK索引中查找,是一个随机IO,外带一个logn的查询开销。 那么当二级索引范围查的扫描列大于一定的数量的时候,explain会发现,prossible_keys显示有索引可走,但是实际的key却没有走索引,type=ALL。 当逐渐缩小二级索引上的查找范围的时候,会发现,mysql会突然又选择去使用prossible_keys下显示的索引了。 举个例子 举个例子: CREATE TABLE `test` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `type` int(11) DEFAULT '0', `status` int(11) DEFAULT '0', `created_at` datetime DEFAULT NULL, PRIMARY KEY (`id`), KEY `idx_create_at` (`created_at`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; created_at列上有一个二级索引。 使用查询语句: SELECT count(*) FROM test WHERE type=? and status=? and created_at>'2020-01-01 00:00:00'; 这时explain: select_type type prossible_keys key Extra SIMPLE ALL idx_create_at NULL Using where 可以看到有索引却没有走。 当我们缩小created_at的范围时: SELECT count(*) FROM test WHERE type=? and status=? and created_at>'2020-03-01 00:00:00'; 这时explain: select_type type prossible_keys key Extra SIMPLE range idx_create_at idx_create_at Using index condition; Using where 发现同样一个语句,在范围查不同的情况下,有时候Mysql会选择不同的方式去进行实际的查找。 刚刚说过了,这种权衡是在较少的随机IO和较多的顺序IO这两者之间抉择的,并不是没有走索引性能就一定会差。 这里count(*)可以换成表中各个具体的列,但是不要用select *,这样不会走索引,原因我还不知道 让mysql强制走索引 也很简单,查询分两步走: SELECT count(*)FROM test as a inner join test as b on a.id=b.id and a.status=? AND a.type=? AND b.created_at>"2020-01-01 00:00:00"; 再次expain: select_type table type prossible_keys key Extra SIMPLE b range PRIMARY,idx_create_at idx_create_at Using where; Using index SIMPLE a eq_ref PRIMARY PRIMARY Using where 发现两次查询都走了索引。 并且使用idx_create_at二级索引的时候,还是用了覆盖索引,因为这一步只取出了PK。 我的个人博客:https://www.jelliclecat.cn/新出炉的RPC框架(如果这篇文章对你有用记得帮我点个star~):https://github.com/zhengrenjie/catty
点赞 1
评论 0
牛客网博客
全部评论
推荐
最新
楼层
暂无评论,快来抢首评~
相关推荐
01-05 17:20
蚌埠坦克学院 嵌入式软件开发
查重真的难受
写论文的过程中,最崩溃的时刻莫过于查重结果出来的那一刻。辛辛苦苦写的内容,被一串数字和重复率击中,让人瞬间怀疑自己的一切努力。那一刻,只想大喊:重写?又要改?但也正是这些崩溃,让我学会更严谨地引用、整理资料,也让论文一步步走向完善。
写论文的崩溃时刻
点赞
评论
收藏
分享
01-06 17:12
睿琪软件_产品经理(准入职员工)
滴滴内推,滴滴内推码
滴滴后端一二面面经一面40min纯技术面,面试官很友好,时不时会对你微笑,然后点头表示肯定,答对了还会说说得对。挑选一个你最想介绍的项目介绍一下,没有深挖。八股盛宴:C++、C、数据结构、数据库。总结就是不是简单的问你什么是虚函数,然后你说个虚指针,虚函数表就完事了。还会问你空指针可以调用类的方法吗?调用虚函数或者非静态成员变量的非虚函数为什么会崩溃?在什么阶段?大概就是这个意思,所以需要对每个方向的知识点有很深的理解,或者说实际开发中切实的应用过才能答得出来。二面25min个人感觉是目前为止碰到的最让人不解的面试官,全程皱着眉头,问的问题我没理解清楚也不会过多解释,直接默认我不会,然后说那我...
点赞
评论
收藏
分享
2025-12-01 13:39
已编辑
东北大学 Java
实习生也得横向吗?
花了两周面了两轮技术面第二轮技术面还迟到了三十分钟最后来个实习时间不够长这种情况正常吗?
Rain_Codin...:
没事,反正都是吹牛逼的,另一个实习生说能实习到毕业,说不定干两个月就跑了,亏的还是他
点赞
评论
收藏
分享
2025-12-02 11:26
湖南大学 安卓
华为开奖——去还是不去
华为这两天开奖闹得沸沸扬扬,口碑真的直线下滑,基本上看到的都是打算不去的,今年开的基本上都是侮辱价,谁去谁亏听说华子进去一切听分配,整不好还真给你分配到测试点。华子开15也比不了互联网大厂的普通sp甚至某些厂的大白菜,甚至他公积金是5%,闹麻了
杜宇杭你在干什么:
华为吗?我其他offer总包是华为的两倍,直接给我开笑了
华为求职进展汇总
点赞
评论
收藏
分享
01-02 15:13
已编辑
晶晨半导体_ENG SW_软件开发工程师
我的秋招回忆录:从惨败到硕果的成长之路
转眼间,我已经是毕业三年的“老社畜”了。作为一名2022年毕业的本科生,我直到现在都没写过一篇完整的秋招总结。今天是2026年1月1日元旦假期,趁着这份闲暇回顾往昔,便想把自己找实习、找工作的经历梳理清楚,好好记录下当年秋招的点滴与心得。初出茅庐,首战惨败!我第一次制作简历是在大二,那年恰逢疫情,所有选修课都在家中线上完成。在哥哥的建议下,我借着他的简历模板开始着手准备,一共做了中英文两份。当时想试着给企业投递简历,可招聘大二实习生的公司本就不多,我在众多企业中筛选出几家投递后,最终只有两家通过了简历筛选——一家是西山居(金山软件的游戏部门),另一家的名字我已经记不清了。那时我的算法能力很差,...
牛友故事会
点赞
评论
收藏
分享
评论
点赞成功,聊一聊 >
点赞
收藏
分享
评论
提到的真题
返回内容
全站热榜
更多
1
...
双非非科班2年时间的转码历程
1.1W
2
...
入职第一天:允许自己像个新生
8314
3
...
26秋招小结 含面经碎碎念版
4394
4
...
师门闯关记①:好学姐我听你的,就选你说的那个导师了
4157
5
...
百度java一面 28届的第一次大厂面试 感觉g了
3608
6
...
实习不忙被公司要求下周再来
3107
7
...
拥抱人机共生,锻造不可替代的“金头脑”
2875
8
...
双非老鼠的悲惨秋招
2601
9
...
测开劝退
2567
10
...
嵌入式学习路线分享
2550
创作者周榜
更多
正在热议
更多
#
26年哪些行业会变好/更差
#
11528次浏览
153人参与
#
卷__卷不过你们,只能卷__了
#
5009次浏览
130人参与
#
去年的flag与今年的小目标
#
5621次浏览
140人参与
#
哪些公司在招寒假实习?
#
5664次浏览
61人参与
#
有深度的简历长什么样?
#
11107次浏览
215人参与
#
腾讯音乐求职进展汇总
#
146848次浏览
1042人参与
#
入职第一天
#
6749次浏览
139人参与
#
写论文的崩溃时刻
#
2657次浏览
90人参与
#
你都用AI做什么
#
4206次浏览
109人参与
#
你不能接受的企业文化有哪些
#
6031次浏览
106人参与
#
一人分享一道面试手撕题
#
14556次浏览
632人参与
#
现在前端的就业环境真的很差吗
#
486711次浏览
5834人参与
#
办公室恋情是职场大忌吗
#
15342次浏览
31人参与
#
海康威视求职进展汇总
#
553624次浏览
3721人参与
#
机械人的秋招小目标
#
25695次浏览
225人参与
#
央国企投递记录
#
169921次浏览
1632人参与
#
应届生应该先就业还是先择业
#
162608次浏览
825人参与
#
实习,不懂就问
#
148194次浏览
1333人参与
#
你的秋招进行到哪一步了
#
2478323次浏览
23235人参与
#
非技术投递记录
#
678298次浏览
6832人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务