MySQL索引

Posted by Liao on 2020-05-13

一、定义

索引是帮助MySQL获取数据的数据结构,也可理解为“排好序的快速查找的数据结构”

索引本身很大,不可能全部存储在内存,因此索引往往会以索引文件的形式存储在磁盘中。

二、索引分类

  • 普通索引:最基本的索引,没任何约束
  • 唯一索引:索引列的值必须唯一,但可以为空
  • 主键索引:特殊的唯一索引,不允许为空
  • 全文索引:MySQL自带的全文索引只用于Innodb、MyISAM,并且只能对英文进行全文检索
  • 外键索引:只有innodb引擎的表才可以建外键索引
  • 单值索引:一个索引只能包含一个列,一个表中可有多个单值索引
  • 复合索引:一个索引可以包含多个列(在并发下偏向于创建复合索引)

1)聚簇索引是主键的术语,找到了索引就找到了所需数据。按照数据存放的物理位置为顺序的,其多个连续行的访问速度更快;

2)非聚簇索引是按照数据存放的逻辑位置为顺序的,其单行访问速度更快;

三、索引的数据结构

  • B-Tree索引(MySQL用B+Tree索引
  • Hash索引
  • full-text全文索引
  • R-Tree索引

B-Tree的检索原理

B-Tree是多路平衡查找树,简称平衡树。

由于索引是存储在磁盘中,磁盘页就相当于树的节点,所以查询数据时,磁盘IO的次数树的高度有关。每次检索的时候为了减少磁盘IO的次数,尽可能把树的高度减少,而宽度增加。这个正是B树的特点。

分别有根、数据项和叶子结点。其中浅蓝色表示磁盘,深蓝色是数据项,红色表示数据,黄色是指针。

B-Tree的数据分布在各个节点上,

非叶子节点不存储真实数据,只存储指引搜索方向的数据项,17,35并不是真实存在数据表中。

索引检索原理

若查找s数据项29,查找过程是:首先把磁盘块1加载到内存,发生1次IO,通过二分搜索确定29在17和35之间,锁定磁盘块的p2指针;通过磁盘1中的p2指针把磁盘块3加载到内存(内存相比磁盘IO的时间非常短,可忽略不计),发生第二次IO。再确定29在26~30之间,通过指针p2把磁盘块8加载到内存,发生第三次IO,再做二分查找,结束查询,共三次IO。

三层的B+Tree可以表示上百万的数据,如果上百万的数据只需三次IO,性能的提升是很大的。若没有索引,每个数据项都发生一次IO,则要上百万的IO,成本很高。

B+树

  • B+树是B树的改进,B+树查询效率更高,B+树通常更矮胖,层数越少,查询所需要的磁盘IO也会更少(一层代表一次IO )。同样的磁盘IO大小,B+树能存储更多的结点关键字
  • 叶子结点增加了相邻接点的指向指针,适用于区间查询
  • B树每个节点即保存数据又保存索引,所以访问磁盘IO的次数多;而B+树只有叶子节点保存,访问磁盘IO数量少,并且区间访问比较好

四、索引优化

  • 不再索引列上做任何操作(计算、函数、类型转换),会导致索引失效

  • 使用全局匹配

  • 最佳左前缀法则:最左建的索引不能丢失,不跳过索引中间列。例如(1-2-3 1 2不能断)

  • 按需取数据,尽量使用覆盖索引,只访问索引的查询,(索引列和查询列一致),减少select *

  • MySQL在使用不等于(!= / <>)/ is null / is not null时会导致索引失效(无法使用索引),导致全表扫描

  • like以通配符(‘%abc’)开头导致MySQL索引失效,变成全表扫描。like%写在右比较好

  • 字符串不加单引号导致索引失效

  • 少用or,用它连接会索引失效

五、优势与劣势

  • 优势
    • 提高数据检索效率,降低数据库IO的成本
    • 降低数据排序成本,降低CPU的消耗
  • 劣势
    • 索引列会占用磁盘空间。索引实际上也是一张表,该表保存了主键和索引字段,并指向实体表的记录。
    • 虽然加大查询速度,但会降低写表的操作(inset,update,delete),对表更新操作的时候,MySQL不仅要保存数据,还要保存索引文件中新添加的索引字段(会调整由于更新带来的键值变化后的索引信息),更新B-tree
    • 要通过人为处理不断调整出最优的索引

六、场景

使用场景
  • 主键自动建立唯一索引
  • 频繁作为查询条件的字段应创建索引
  • 查询中与其他表关联的字段,外键关系建立索引
  • 排序字段若通过索引访问会大大提高排序速度
不适用的场景
  • 表太少的记录

  • 经常增删改的表

    • 虽然提高了查询表的速度,但会降低更新表的速度(增删改),因为在更新表时,MySQL不仅保存数据,还得保存索引文件
  • 某个数据列包含许多重复内容,为其建索引没有太大的实际效果(男女)

    索引选择性 = 索引列中不同值的数目/表中记录数,索引选择性越接近1,该索引效率越高。

  • Where条件用不到的字段不创建索引