Mysql索引篇

索引简述

索引是一种特殊的文件(InnoDB存储引擎数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。

索引是一种数据结构。数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。索引的实现通常使用B树及其变种B+树。更通俗的说,索引就相当于目录。为了方便查找书中的内容,通过对内容建立索引形成目录。而且索引是一个文件,它是要占据物理空间的。

MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度。比如我们在查字典 的时候,前面都有检索的拼音和偏旁、笔画等,然后找到对应字典页码,这样然后就打开字典的页数就可以知道我们要搜索的某一个key的全部值的信息了。

但是,创建索引和维护索引要耗费时间,具体地,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,会降低增/改/删的执行效率;另外,索引需要占物理空间。

Mysql索引类型

普通索引:即一个索引只包含单个列,一个表可以有多个单列索引

唯一索引:索引列的值必须唯一,但允许有空值

复合(组合)索引:多列值组成一个索引,专门用于组合搜索,其效率大于索引合并

聚簇索引(也叫聚集索引、主键索引):并不是一种单独的索引类型,而是一种数据存储方式。具体细节取决于不同的实现,InnoDB的聚簇索引其实就是在同一个结构中保存了B-Tree索引(技术上来说是B+Tree)和数据行。

非聚簇索引:不是聚簇索引,就是非聚簇索引

从存储结构:BTree索引(B-Tree或B+Tree索引),Hash索引,full-index全文索引

从应用层次:普通索引,唯一索引,复合索引。

从数据的物理顺序与键值的逻辑(索引)顺序关系:聚簇索引,非聚簇索引。

聚簇索引和非聚簇索引

在InnoDB里,索引B+Tree的叶子节点存储了整行数据的是主键索引,也被称之为聚簇索引,即将数据存储与索引放到了一块,找到索引也就找到了数据。

而索引B+ Tree的叶子节点存储了主键的值的是非主键索引,也被称之为非聚簇索引、二级索引。

非聚簇索引与聚簇索引的区别在于非聚簇索引的叶子节点不存储表中的数据,而是存储该列对应的主键(行号)

对于InnoDB来说,想要查找数据我们还需要根据主键再去聚簇索引中进行查找,这个再根据聚簇索引查找数据的过程,我们称为回表。

第一次索引一般是顺序IO,回表的操作属于随机IO。需要回表的次数越多,即随机IO次数越多,我们就越倾向于使用全表扫描。

通常情况下,主键索引(聚簇索引)查询只会查一次,而非主键索引(非聚簇索引)需要回表查询多次。当然,如果是覆盖索引的话,查一次即可。

注意:MyISAM无论主键索引还是二级索引都是非聚簇索引,而InnoDB的主键索引是聚簇索引,二级索引是非聚簇索引。我们自己建的索引基本都是非聚簇索引。

非聚簇索引一定会回表吗

不一定,这涉及到查询语句所要求的字段是否全部命中了索引,如果全部命中了索引,那么就不必再进行回表查询。一个索引包含(覆盖)所有需要查询字段的值,被称之为"覆盖索引"。

举个简单的例子,假设我们在员工表的成绩上建立了索引,那么当进行select score from student where score >90的查询时,在索引的叶子节点上,已经包含了score 信息,不会再次进行回表查询。

MySQL可以使用多个字段同时建立一个索引,叫做联合索引。

MySQL的联合索引时会遵守最左前缀匹配原则,即最左优先,在检索数据时从联合索引的最左边开始匹配,否则大概率无法命中索引。

具体描述:

MySQL使用索引时需要索引有序,假设现在建立了"name,age,school"的联合索引,那么索引的排序为:先按照name排序,如果name相同,则按照age排序,如果age的值也相等,则按照school进行排序。

当进行查询时,此时索引仅仅按照name严格有序,因此必须首先使用name字段进行等值查询,之后对于匹配到的列而言,其按照age字段严格有序,此时可以使用age字段用做索引查找,以此类推。

因此在建立联合索引的时候应该注意索引列的顺序,一般情况下,将查询需求频繁或者字段选择性高的列放在组合索引的最左边。

Btw: MySQL 8.0.13版本引入了Skip Scan Range Access Method,它在一定条件下可以不遵守最左前缀原则,利用了范围扫描来替代了全表扫描的发生。

原理为:MySQL隐式的构造了前缀查询条件,使一条查询就变成了多次查询,执行计划type = range。适用于最左条件区分度较低的情况,否则生成SQL过多,与全表扫描相比并无优势。

前缀索引

有可能索引的字段非常长,这既占内存空间,也不利于维护。所以,如果只把很长字段的前面的一部分作为一个索引,并且索引区分度很高的话,就会产生不错的均衡的效果。

相关推荐

  1. Mysql索引

    2024-04-27 03:16:03       13 阅读
  2. MySQL索引创建与失效

    2024-04-27 03:16:03       30 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-27 03:16:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-27 03:16:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-27 03:16:03       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-27 03:16:03       20 阅读

热门阅读

  1. 什么是prettier的glob 模式

    2024-04-27 03:16:03       15 阅读
  2. 【DataGrip】 sql语句:模糊搜索

    2024-04-27 03:16:03       14 阅读
  3. 删除有序序列中的重复项 python

    2024-04-27 03:16:03       14 阅读
  4. Jammy@Jetson Orin - Tensorflow & Keras Get Started

    2024-04-27 03:16:03       13 阅读
  5. 面试题:判断一个完全平方数

    2024-04-27 03:16:03       15 阅读
  6. Ali-Sentinel-入口控制

    2024-04-27 03:16:03       14 阅读
  7. SQL数据更新

    2024-04-27 03:16:03       12 阅读
  8. Vue-3

    Vue-3

    2024-04-27 03:16:03      11 阅读
  9. C# 面向对象编程(一)——类 第三篇

    2024-04-27 03:16:03       13 阅读
  10. DataGridView控件

    2024-04-27 03:16:03       13 阅读
  11. Redis的单线程模型解析与应用实践

    2024-04-27 03:16:03       12 阅读
  12. 基于nest框架的redis streams实现mq(bullmq)

    2024-04-27 03:16:03       15 阅读