【mysql 索引相关知识点

2023年 9月 28日 46.6k 0

mysql索引

聚簇索引

也叫聚集索引,第一索引。

聚簇索引一般是主键索引,如果没有主键索引,那么就使用唯一索引,如果没有唯一索引,那么就使用唯一的row_id,这个是一个隐藏值,如果没有前面说的那些索引,每一行会自动生成row_id。

聚集索引的结构

聚集索引内部是使用B+树结构来进行构建的, 而B+树的结构为内部节点与叶子节点:

Mysql中B+树的特性

  • 我们使用的mysql存储引擎是Innodb
  • InnoDB存储引擎最小储存单元是页,一页大小就是16k
  • 每个节点的大小都是一页,这个页可以自定义,默认是16K
  • 内部节点(非叶子节点)不存储数据,只存储指针和聚簇索引的值
  • 叶子节点存储真实的数据行
  • 索引值是有序的

B+树结构类似于下图:

image.png

图里的data就是真实数据。

查询的效率是很高的,每一层根据二分法来寻找指定的索引值。

非聚簇索引的结构

非聚簇索引与聚簇索引类似,但是它叶子节点不存完整数据,而是存聚簇索引值。

非聚簇索引的特点

  • 非叶子节点存储索引列的值
  • 叶子节点存储索引列及对应的聚簇索引的值
  • 二级索引获取除二级索引值外的数据需要走一遍聚集索引
  • 搞懂聚簇索引和非聚簇索引的结构之后,就可以来解释一些相关知识点。

    索引进行和等值,范围查询

  • 等值查询: 去B+树叶子节点找到某一个页,然后遍历这个页,就能找到指定值。

  • 范围查询: 先根据等值查询找到指定值, 然后往后或往前遍历数据,找到范围值。

  • 联合索引

    联合索引在B+树中的结构形如下:

    假设有一个索引(a,b,c):

    a b c
    1 5 10
    1 8 8
    3 8 12
    6 10 15
    7 11 4
    10 6 1
    10 6 2

    从a开始排序,保证a总体为非递减序列; 当a相同, 保证b为非递减序列; 当b相同,保证c为非递减序列

    出几道题来加深理解:

    索引(a,b,c)

  • select * from t where a = 1 and b = 3 and c = 2;
    先匹配a,再匹配b,再匹配c。
  • select * from t where a = 1 and b > 3 and c = 5;
    先匹配到a, 然后在找到b大于3的部分,这个时候c是没有顺序的,因此c会匹配失效
  • select * from t where a > 5 and b = 5 and c = 5;
    先匹配a的部分,然后b是无序的,所以后面部分的索引匹配会失效。
  • select * from t where b = 5; 会失效,因为b在(a,b,c)中,a不确定的情况下,b是无序的,因此会失效
  • 索引覆盖

    比如有索引(a,b), 我查找 select a,b from t where a = 1 and b = 2;

    索引覆盖: 当我们使用二级索引时,所要查找的列刚好被包含在二级索引中,我就不用去聚集索引找数据了。

    这就叫索引覆盖。

    回表

    什么是回表,回表是一种操作,当上面的索引覆盖失效了的时候,就会进行回表操作。

    比如有索引(a, b), 我执行select a,b,c from t where a = 1 and b = 2 , 这个时候会去二级索引获取查a, b。

    但是我二级索引里面并没有c的数据,因此二级索引拿到聚集索引的值,去聚集索引里面走一遍,获取数据。

    为什么不建议使用UUID做主键

  • UUID无序,添加数据很容易动整个B+树,进行分裂合并。
  • UUID字段长, 占用内存大,导致节点里面存的数据变少,树变高,IO次数增多
  • 为什么长字段要拆成附表

    page存的数据越多,树越高,导致IO次数多

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论