节点|曾经,我以为我很懂MySQL索引...


北京联盟_本文原题:曾经 , 我以为我很懂MySQL索引...
腾讯云数据库负责人林晓斌说过:“我们面试 MySQL 同事时只考察两点 , 索引和锁” 。
节点|曾经,我以为我很懂MySQL索引...
本文插图
图片来自 Pexels

言简意赅 , MySQL 索引的重要性不言而喻 。 MySQL 索引历经了多个版本的迭代 , 从语法到底层数据结构都有很多改变 。
MySQL 索引 , 我们真的了解么?好了 , 今天我们一起来看看 MySQL 索引的前世今生 , 一起聊聊索引的那些事儿 。
节点|曾经,我以为我很懂MySQL索引...
本文插图

什么是索引?
在关系数据库中 , 索引是一种单独的、物理的对数据库表中一列或多列的值进行排序的一种存储结构 , 它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单 。
索引的作用相当于图书的目录 , 可以根据目录中的页码快速找到所需的内容 。
当表中有大量记录时 , 若要对表进行查询:

  • 第一种搜索信息方式是全表搜索 , 是将所有记录一一取出 , 和查询条件进行一一对比 , 然后返回满足条件的记录 , 这样做会消耗大量数据库系统时间 , 并造成大量磁盘 I/O 操作 。
  • 第二种就是在表中建立索引 , 然后在索引中找到符合查询条件的索引值 , 最后通过保存在索引中的 ROWID(相当于页码)快速找到表中对应的记录 。
MySQL 5.5 以后 InnoDB 储引擎使用的索引数据结构主要用:B+Tree;本篇文章带大家以 B+Tree 前世今生为主线来聊一聊 。
Mark:B+Tree 可以对 < , <= , = , > , >= , BETWEEN , IN , 以及不以通配符开始的 LIKE 使用索引 。 (MySQL 5.5 后)
这些事实或许会颠覆你的一些认知 , 比如在你读过的其他文章或书中 。 以上这些都属于“范围查询” , 都是不走索引的!
没错 , 早在 5.5 以前 , 优化器是不会选择通过索引搜索的 , 优化器认为这样取出的行多与全表扫描的行 , 因为还要回表查一次嘛 , 可能会涉及 I/O 的行数更多 , 被优化器放弃 。
经过算法(B+Tree)优化后 , 支持对部分范围类型的扫描(得利与 B+Tree 数据结构的有序性) 。
该做法同时也违反了最左前缀原则 , 导致范围查询后的条件无法用到联合索引 , 我们在后面详细说明 。
索引的优缺点
索引的优点如下:
  • 索引大大减小了服务器需要扫描的数据量 。
  • 索引可以帮助服务器避免排序和临时表 。
  • 索引可以将随机 I/O 变成顺序 I/O 。
索引的缺点如下:
  • 虽然索引大大提高了查询速度 , 同时却会降低更新表的速度 , 如对表进行 INSERT、UPDATE 和 DELETE 。 因为更新表时 , MySQL 不仅要保存数据 , 还要保存索引文件 。
  • 建立索引会占用磁盘空间的索引文件 。 一般情况这个问题不算严重 , 但如果你在一个大表上创建了多种组合索引 , 且伴随大量数据量插入 , 索引文件大小也会快速膨胀 。
  • 如果某个数据列包含许多重复的内容 , 为它建立索引就没有太大的实际效果 。
  • 对于非常小的表 , 大部分情况下简单的全表扫描更高效 。
因此应该只为最经常查询和最经常排序的数据列建立索引 。 (MySQL 里同一个数据表里的索引总数限制为 16 个)
数据库存在的意义之一就是是解决数据存储和快速查找的 。 那么数据库的数据存在哪?没错 , 是磁盘 , 磁盘的优点是啥?便宜!缺点呢?相比内存访问速度慢 。
那么你知道 MySQL 索引主要使用的数据结构么?B+树!你脱口而出 。
那 B+树是什么样的数据结构?MySQL 索引又是为什么选择了 B+树呢?


推荐阅读