《MySQL面试小抄》索引考点二面总结
我是肥哥,一名不专业的面试官!
我是囧囧,一名积极找工作的小菜鸟!
本期主要面试考点
面试官考点之谈谈索引维护过程?页分裂?页合并?
面试官考点之简述一下查询时B+树索引搜索过程?
面试官考点之什么是回表?
面试官考点之什么是索引覆盖?使用场景?
面试官考点之什么情况下会索引失效?
面试官考点之哪些情况下,可能会面临索引失效的问题?
面试官考点之or走索引和索引失效分别是什么场景?
面试官考点之哪些情况下需要创建索引?
面试官考点之联合索引之最左前缀原则?
面试官考点之索引下推场景?
面试官考点之谈谈索引维护过程?页分裂?页合并?
B+树为了维护索引有序性,在插入删除的时候需要做必要的维护,必要时候可能涉及到页分裂,页合并过程!
首先假设每个叶子节点(数据页或磁盘块)只能存储3条索引和数据记录,如图
页分裂过程消耗性能,同时空间利用率也降低了
有分裂就有合并,当相邻两个页由于删除了数据,利用率很低之后,会将数据页做合并。合并的过程,可以认为是分裂过程的逆过程。
当相邻两个页由于删除了数据,利用率很低之后,会将数据页做合并。合并的过程,可以认为是分裂过程的逆过程。
【数据页2】删除了ID=7,ID=8的行记录,此时【数据页2】【数据页3】利用率很低,将进行页合并。
面试官考点之简述一下查询时B+树索引搜索过程?
准备一张用户表,其中id为主键,age为普通索引
CREATE TABLE `user` (
`id` int(11) PRIMARY KEY,
`name` varchar(255) DEFAULT NULL,
`age` int(11) DEFAULT NULL
KEY `idx_age` (`age`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
select * from user where age=22 简述一下B+树索引搜索过程?
假设要查询的记录
id=5,name="张三",age=22
MySQL为每个索引分别维护了一棵B+Tree索引树,
主键索引非叶子节点维护了索引键,叶子节点存储行数据;
非主键索引也称为二级索引,非叶子节点存储主键;
B+树索引搜索过程
搜索条件 age=22,可走idx_age索引,首先加载idx_age索引树,找到age=22的记录,取得id=5
回表搜索,加载主键索引树,找到id=22的记录,取得整行数据
面试官考点之什么是回表?
idx_age二级索引树找到主键id后,回到id主键索引搜索的过程,就称为回表。
并非所有非主键索引搜索,都需要进行回表搜索,也就是下面要说的索引覆盖。
面试官考点之什么是索引覆盖?使用场景?
在上面提到的例子中,由于查询结果所需要的数据只在主键索引上有,所以不得不回表。
如果在查询的数据列里面,直接从索引列就能取到想要的结果,就不需要再回表去查,也称之为索引覆盖!
索引覆盖的优点
select id, age from user where age=22
查询的信息,id,age都可以直接在idx_age 索引树中获取,不需要回表搜索。
由于覆盖索引可以减少树的搜索次数,显著提升查询性能,所以使用覆盖索引是一个常用 的性能优化手段。
索引是一把双刃剑,提供快速排序搜索的同时,索引字段的维护也是要付出相应的代价的。
因此,在建立冗余索引来支持覆盖索引时就需要权衡考虑了
面试官考点之索引失效?
一个最常见的查询场景,建立idx_name索引
select * from t_user where user_name like '%mayun100%';
select * from t_user where user_name like 'mayun100%';
面试官考点之有哪些情况下,可能会面临索引失效的问题?
面试官考点之or走索引和索引失效分别是什么场景?
explain select * from t_user where user_name = 'mayun10' or user_name = 'mayun1000'
alter table t_user add index idx_address(address);
explain select * from t_user where user_name = 'mayun10' or address = '浙江杭州12';
面试官考点之哪些情况下需要创建索引?
面试官考点之联合索引之最左前缀原则
MySQL建立多列索引(联合索引)有最左前缀的原则,即最左优先
当MySQL建立的是联合索引,假设以(a,b,c) 列作为联合索引,那么MySQL建树规则是什么?
我们知道MySQL会为每一个索引维护一颗B+Tree,非叶子节点存储索引key,叶子节点存储行数据data。
联合索引(a,b,c) 相当于建立了 (a), (a,b), (a,b,c) 三个索引,MySQL组装索引树时,是按照从左到右的顺序来建立B+Tree的联合索引树的。
匹配索引情况一
匹配索引情况二
匹配索引情况三
索引项是按照索引定义里面出现的字段顺序排序的,最左前缀可以是联合索引的最左N个字段,也可以是字符串索引的最左M个字符。
面试官考点之索引下推场景?
索引下推,即减少二级索引回表搜索次数!!!
通俗说,减少查询主键索引树次数,减少磁盘IO
建立联合索引 idx_age_weight
select * from user where age = 11 and weight = 98
5.6之前搜索过程是
在idx_age_weight 索引树中匹配出所有的 age = 11 索引,拿到主键id,回表去一条条再比对weight字段
如下图,需要进行3次回表搜索操作
5.6后的搜索过程是 在idx_age_weight 索引树中匹配出所有的 age = 11 索引,顺便对weight字段进行判断,过滤掉weight = 100的记录,然后再进行回表搜索。
如下图,只需要进行2次回表搜索操作