数据库
首页 > 数据库> > Mysql-索引

Mysql-索引

作者:互联网

按存储方式分

  1. B-树,B+树
  2. 哈希索引
    Memory引擎默认索引时哈希索引

逻辑区分

  1. 普通索引
  2. 主键索引:mysql会自动为主键创建主键索引
  3. 唯一索引:索引值必须唯一的普通索引
  4. 全文索引
  5. 空间索引:MyISAM引起支持,用于地理空间数据类型GEOMETRY,SPATIAL关键字

实际使用划分

  1. 单例索引
  2. 多列索引

Innodb的聚集索引和非聚集索引

1.聚集索引
索引键值和数据紧凑存储在一起,索引的逻辑顺序和数据的物理顺序一致。InnoDB中聚集索引叶子节点直接存储的是整条数据。
2. 非聚集索引
索引和数据不在一起,叶子节点保存的是当前索引键值和主键索引键值。
通过非聚集索引查询到主键之后,需要根据主键键值去扫描主键索引的B+树,这种操作叫做回表。

B-树和B+树区别

  1. m阶B-树节点最多存储m-1个值,B+树可以存储m个值
  2. B+树的非叶子节点不保存数据,只保存指针同样大小的节点可以保存更多的key,树就更矮IO次数更少。非叶子节点的key最后都会存在于叶子节点里,而且是叶子节点的最大值或最小值。
  3. B+树因为最终的数据是保存在叶子节点里,所以IO次数是稳定的。
  4. B+树的叶子节点构成一个有序链表。便于范围查找。

MyISAM引擎的索引

MyISAM引擎不支持事务,不支持外键,不支持行级锁,只支持表级锁。适用于读多写少的场景。记录行数不需要遍历全部行来统计行数。

MyISAM中叶子节点存储的是当前索引值和当前数据文件对应的磁盘地址。主键索引和非主键索引没有区别。

主键索引为什么速度快

因为主键索引不需要回表。只扫描一颗B+树

索引下推

5.6以前,存储引擎遍历索引后把数据返回给Server层,由Server层进行where条件计算。
5.6 开始,部分where条件可以通过索引中的列进行计算时,存储引擎会进行这部分where条件的计算,减少回表次数和返回给Server层的数据量。

多范围读

5.6以后,减少磁盘的随机IO访问,进可能的把随机访问转换为顺序访问。
缓存辅助索引键值,按照主键进行排序,然后按照主键顺序进行访问。

索引合并

5.0之后,表中建立了很多单例索引,查询时用了很多列,mysql能识别单列索引进行扫描,然后把结果合并。
or条件的并集 union ,and的交集。

MySQL如何选择索引

MySQL选择索引是根据开销来选择。

索引判断基数Cardinality

Cardinality:索引中唯一值的估计值,越接近行数,索引的选择性越高。

Cardinality是通过采样来实现计算的,并不是一个精确值,而是一个统计值。并不会实时更新,更新会带来一定开销。

Cardinality更新策略:

  1. 表中1/M的数据发生变化,1/16
  2. 数据变化次数超过一定值,少量行频繁更新的情况下。
    即发生变化的行数或次数达到一定值。

Cardinality计算方式

InnoDB默认对N个叶子节点进行抽样:

  1. 获得叶子节点总是A
  2. 随机获得N个叶子节点,统计每个叶子节点不同记录个数获得总数total
  3. total ÷ N 得到平均每个叶子节点不同记录个数
  4. total ÷ N × A
    即随机采样N个叶子节点,统计每个叶子节点唯一值个数,然后得到这N个叶子节点的唯一值平均值,然后用这个平均值乘叶子节点总数A。

离散度

即Cardinality与count(*)之比

可以强制使用某个索引force index
建议使用某个索引use index

最左匹配原则

  1. 模糊查询
    like语句,对关键字从左到右进行匹配,如果第一个字符不确定则无法使用
  2. 多列索引
    如a,b两列索引,条件只有b时失效。因为索引是按照先a有序再b有序存储的。

无法使用索引的情况

  1. 在索引列上使用函数,加减乘除计算
  2. 字符串不加引号
  3. 使用 !, <>,not like, not in 反向查询

标签:存储,节点,叶子,索引,Mysql,Cardinality,主键
来源: https://www.cnblogs.com/baiyutang7/p/16679052.html