前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >mysql索引十连问| 剑指offer - mysql

mysql索引十连问| 剑指offer - mysql

作者头像
会玩code
发布于 2022-04-24 06:06:39
发布于 2022-04-24 06:06:39
9780
举报
文章被收录于专栏:会玩code会玩code
以下是结合网上及此前面试时遇到的一些关于 mysql 索引的面试题。若对 mysql 索引不太了解可先翻阅相关文章

什么是索引?

索引类似书本的目录,查询书中的指定内容时,先在目录上查找,之后可快速定位到内容位置。在数据库中通常通过 B 树 / B + 树数据结构实现。

主键索引和非主键索引有什么区别?

主键索引树中叶子节点存储的是整行数据,而非主键索引叶子节点上保存的是主键的值。使用非主键索引时,先从非主键索引获取到行对应主键 ID,之后再根据 id 在主键索引树上搜索对应行数据,这个过程也被称为回表。

一般使用什么字段作为主键,为什么?

一般使用 innodb 的自增整数类型作为主键:

  • 因为自增,容易保证主键索引的有序性,同时还能避免新数据中间位置插入时导致的页分裂;
  • 二级索引叶子节点上保存的是主键值,整数类型主键长度较小,二级索引树占用的空间较小。

索引使用场景

where

为查询条件字段创建索引,以达到快速过滤指定条件数据的目的。

order by

当使用 order by 将查询结果按某个字段排序时,可考虑为该字段创建索引。没有索引时,会先将查询结果放到内存中进行排序(若内存空间不足,会利用磁盘辅助排序),比较影响查询效率。索引本身是有序的,可以直接按索引的顺序逐条回表取出数据即可。如果是分页查询,效果更好,这时候只需要取出某个范围的索引对应的数据,而不需要取出所有满足条件的数据排序后再截取返回分页数据。

join

使用 join 时,为被驱动表的关联字段创建索引,可以有效提高查询效率。比如 select * from t1 straight_join t2 on (t1.a=t2.a) where t1.b = 'xxxx'; t2 的字段 a 上有索引,查询过程会是先从表 1 中依次取出满足条件的行数据,之后用行数据中的 a 字段去 t2 上匹配后将两表字段拼接返回,此时能使用到 t2.a 的索引,避免了 t2 全表扫描。

索引覆盖

如果 select 字段 + where 字段字段列数不太多且查询频繁时,可以考虑为 select 和 where 字段创建联合索引,避免查询时回表,提高查询效率。比如 select a from t where b = ‘xx’, 创建联合索引 (b, a), 此时扫描索引树后,就已经得到需要查询的字段 a 了,不需要再回表。需要注意的是联合索引字段的顺序,这个语句无法使用到索引 (a, b)。

创建索引需要注意的地方

  • 最左前缀匹配原则,联合索引需要注意索引字段的顺序,mysql 会一直向右匹配直到遇到范围查询 (>、<、between、like) 就停止匹配,比如 a = 1 and b = 2 and c > 3 and d = 4 , 如果建立 (a,b,c,d) 顺序的索引,d 是用不到索引的。字段是否用到索引的意思是字段是否能利用字段在索引中的有序性进行快速过滤。索引 (a,b,c,d), 在索引树上是先按 a 进行排序,再按 b 进行排序,以此类推,排序规则类似 order by a,b,c,d。上面查询条件中,a 定值,b 是有序的;b 定值,c 是有序的;c 范围查询,剩下的 d 是无序的。所以 d 无法使用到该索引。
  • 基数小,区分度低的不适合创建索引。比如性别,最多基数最多总共就 3 个,此时索引过滤性能不高,查完索引后还需回表,可能比直接全表扫描效率更低。
  • 更新频繁的字段创建索引时要权衡索引维护成本。
  • 尽量扩展索引,比如已经有 a 索引,现在要加 (a,b) 的索引,那么只需要修改原来的索引即可。
  • 避免对 text 大字段创建索引,会导致索引树太大,查询效率不高。如果大字段前 n 个字符区分度较高,可以考虑创建前缀索引,只索引开始的部分字符,这样可以节约索引空间,提高索引效率。其缺点是不能用于 ORDER BY 和 GROUP BY 操作,也不能用于覆盖索引 (因为前缀索引树上只有字段的部分内容,需要进行回表)。

什么时候索引会失效?

  • 模糊查询时查询条件以”%” 开头无法使用到索引
  • 使用 or 查询时,只有当所有的查询条件字段都有索引才能使用到,比如 a=1 or b = 2, 只有当 a 和 b 都有索引才能使用到索引。
  • 数据类型出现隐式转换,如 varchar 不加单引号的时候可能会自动转换为 int 类型,这个时候索引失效。
  • 在索引列上使用 IS NULL 或者 IS NOT NULL 时候,索引失效,因为索引不会索引空值。
  • 在索引字段上使用”NOT、 <>、!=、NOT IN “时是不会使用索引的,这时只会进行全表扫描。
  • 对索引字段进行计算操作,函数操作时不会使用索引。
  • 当优化器觉得全表扫描速度比索引速度快的时候不会使用索引。一般出现在全表数据比较少的情况下,这时全表扫描比在非主键索引上查找后再回表速度可能更快。
  • 联合索引时,查找不满足最左匹配规则,无法使用到联合索引。

innodb 使用 b + 树作为索引模型的原因

Mysql 设计的使用场景比较广泛,需要对遍历查询、单条查询、数据更新都需要较好的性能支持。B + 树的特性是只在叶子节点上存储数据。可以从数据读写方面与哈希表、有序数组、b 树其他几种索引模型进行比较:

  • 哈希表:哈希表只能进行等值查询,在处理范围查询和排序查询时,需要全表扫描哈希表。
  • 有序数组:有序数组在进行数据更新时成本较大。往数组中间位置添加数据时,需要移动后面的数据位置。
  • B 树:b 树在非叶子节点上也存储数据,在遍历数据时,需要对不同层级的节点上的数据进行拼接和排序,这会导致多次磁盘 io。查询效率较低。

如何删除百万级别或以上的数据?

可以考虑先删掉表的索引,等删除数据后再重建索引。当我们在进行数据修改时,需要同时修改索引,这些额外的索引维护成本较低数据修改的效率;同时,大量的数据删除会导致索引数据页产生大量的碎片空间,此时删除数据后重建索引可以使索引树更 “紧凑”,提高磁盘空间利用率。

Innodb 中的 B + 树模型中,N 叉树的 N 能否被修改?

  1. 通过调整索引字段大小来修改 N 叉树中非叶子节点存放的是索引信息,索引包含 Key 和 Point 指针。Point 指针固定为 6 个字节,假如 Key 为 10 个字节,那么单个索引就是 16 个字节。如果 B + 树中页大小为 16 K,那么一个页就可以存储 1024 个索引,此时 N 就等于 1024。我们通过改变 Key 的大小,就可以改变 N 的值。
  2. 通过修改页大小间接修改,页越大,每页存放的索引数量就越多,N 就越大。

数据页调整后,如果数据页太小层数会太深,数据页太大,加载到内存的时间和单个数据页查询时间会提高,需要达到平衡才行。

如何知道语句有没有走索引查询?

可以利用 explain 查看 sql 语句的执行计划,通过执行计划来分析索引使用情况。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-04-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 会玩code 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
MySQL索引
索引需要保存到磁盘上,假设我们使用平衡二叉树来存储,一个100万个节点的二叉树高20,一次查询需要访问20个数据块,机械硬盘随机读取一个数据块大约需要10ms时间,因此单独访问一个行大约需要200ms时间。
shysh95
2022/02/16
4.2K0
MySQL索引
MySQL原理简介—9.MySQL索引原理
数据库所有的数据都会存放到磁盘上的文件,数据在文件里存放的物理格式就是数据页,大量的数据页会按顺序一页一页存放的,两两相邻的数据页之间会采用双向链表的格式互相引用。
东阳马生架构
2025/02/09
1310
MySQL索引(深入浅出)
索引的作用就是为了加快搜索,计算机要处理的数据非常复杂,为了快速检索多种多样的数据,聪明的程序员们就发明了各种类型的索引。
一行舟
2022/08/25
4510
MySQL索引(深入浅出)
数据库索引,你要了解的都在这里!
数据库索引好比是一本书前面的目录,能加快数据库的查询速度。索引是对数据库表中一个或多个列(例如,User 表的 '姓名' 列)的值进行排序的结构。如果想按特定用户的姓名来查找他或她,则与在表中搜索所有的行相比,索引有助于更快地获取信息。
JAVA日知录
2020/05/09
6200
MySQL索引原理探索
索引的本质其实就是各种各样的数据结构,在增删改查的各种操作有不通的时间复杂度和空间复杂度
晓果冻
2022/09/08
2650
MySQL索引原理探索
MySQL索引原理
MySQL索引原理 MySQL 的索引 概述 索引是数据库中一个排序的数据结构,用来协助快速查询和更新数据库表中的数据;数据是以文件的形式存放在磁盘上的,每一行数据都有它的磁盘地址;当没有索引时,比如从 **500w** 条数据中检索出一条数据,只能依次遍历这张表的全部数据,直到找到这条数据。但是有了索引后,只需要在索引里去检索这条数据就可以了,因为它是一种专门进行数据检索特殊的数据结构,在找到数据存放的磁盘地址后就可以拿到数据。在 **InnoDB** 存储引擎中,索引有三类: 普通(**norm
编程之心
2021/07/14
4630
MySQL索引原理
MySQL基础索引小结
多个 key 值经过哈希函数的换算,会出现同一个值的情况。处理这种情况的一种方法是,拉出一个链表。
WindCoder
2020/01/23
4980
MySQL索引的原理及使用
  上篇文章中学习了MySQL库的架构以及存储引擎,了解了基本索引(普通索引,唯一索引,主键索引),着重介绍了innerDB的存储方式以及内存模型,本篇文章和大家探讨一下MySQL库中索引的原理以及索引底层的数据结构。
会说话的丶猫
2020/08/06
9940
MySQL索引的原理及使用
MySQL索引由浅入深
MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构,索引对于良好的性能非常关键,尤其是当表中的数据量越来越大时,索引对于性能的影响愈发重要。索引优化应该是对查询性能优化最有效的手段了。索引能够轻易将查询性能提高好几个数量级。
三分恶
2021/03/05
7760
MySQL索引由浅入深
MySQL中的索引和锁
索引常见的类型有哈希索引,有序数组索引,二叉树索引,跳表等等。本文主要探讨 MySQL 的默认存储引擎 InnoDB 的索引结构。
用户1212940
2019/11/02
1.1K0
MySQL索引数据结构入门
之前松哥写过一个 MySQL 系列,但是当时是基于 MySQL5.7 的,最近有空在看 MySQL8 的文档,发现和 MySQL5.7 相比还是有不少变化,同时 MySQL 又是小伙伴们在面试时一个非常重要的知识点,因此松哥打算最近再抽空和小伙伴们聊一聊 MySQL,讲讲原理,讲讲优化,我会从最基本最简单的开始,和大家梳理 MySQL 中常见的面试知识点。
江南一点雨
2024/04/18
1990
MySQL索引数据结构入门
MySQL InnoDB索引:存储结构
此小结与索引其实没有太多的关联,但是为了便于理解索引的内容,添加此小结作为铺垫知识。
AlbertZhang
2020/09/21
1.2K0
Mysql索引原理及应用场景
在工作当中,涉及到Mysql的查询,我们经常会遇到给某个表某个字段加索引的诉求,加上索引能够让我们的sql得到查询速度上的提升。但索引的原理是什么呢,他又是怎么工作的,需要开发者对基础知识有一定的了解。
benym
2022/08/30
1.3K0
Mysql索引原理及应用场景
MySQL灵魂十连问
连接器:TCP握手后服务器来验证登陆用户身份,A用户创建连接后,管理员对A用户权限修改了也不会影响到已经创建的链接权限,必须重新登陆。
熬夜的花斑狗
2022/08/19
1.1K0
你必须懂的一些MySQL索引技巧
为了更好地进行解释,我创建了一个存储引擎为InnoDB的表user_innodb,并批量初始化了500W+条数据。包含主键id、姓名字段(name)、性别字段(gender,用0,1表示不同性别)、手机号字段(phone),并为name和phone字段创建了联合索引。
蝉沐风
2022/08/11
6300
你必须懂的一些MySQL索引技巧
mysql系列-索引
常见的数据结构中, 哈希表和二叉平衡树的查找效率分别是O(1)和O(logn), 是效率最快的两个, MySQL也毫不意外的使用了这两种数据结构来做索引。 MySQL索引的数据结构有两种选择, B+Tree 和 Hash。
用户6182664
2022/11/14
7000
最详细的 MySQL 执行计划和索引优化!
不管是工作中,还是面试中,关于mysql的explain执行计划以及索引优化,都是非常值得关注的。
田维常
2023/08/31
9110
最详细的 MySQL 执行计划和索引优化!
博文看了这么多,终于理解了MySQL索引
  使用索引避免全表扫描,提高检索效率,使用索引后就维护了一颗B+树,B+树是为磁盘或者其他直接存取辅助设备设计的一种平衡查找树,在B+树中,所有记录节点都是按键值的大小顺序存放在同一层的叶子结点,各叶子结点通过指针进行连接(这里我默认大家最最基本的数据结构知识都会)。
砖业洋__
2023/05/06
2760
博文看了这么多,终于理解了MySQL索引
相关推荐
MySQL索引
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档