MySQL

154 阅读4分钟

1.索引概述

索引是帮助MySQL高效获取数据的数据结构。在没有索引时,查询数据会进行全表扫描,查询速度慢,创建索引后,会在指定的字段上形成一个索引的数据结构,如二叉树,减少磁盘I/O次数,从而大大提升查询的效率。

2.索引的优缺点

优点:

  • 提高数据的检索效率,降低数据库的I/O成本。
  • 创建唯一索引,保证每行数据的唯一性。
  • 加速表与表之间的连接,增加查询效率。
  • 减少查询中分组和排序的时间。

缺点:

  • 创键的索引为数据结构,会占用磁盘空间。
  • 创建和维护索引需要耗费时间。
  • 降低更新表的速度,会影响DML语句的效率(需要对索引进行维护)

索引可以提高查询速度但会影响插入记录的速度,可以先删除索引,再插入数据,所有数据插入之后重新创建索引

3.索引的分类

  • 功能逻辑上分为4种:普通索引、唯一索引、主键索引、全文索引
  • 按照物理实现方式分为2种:聚簇索引和非聚簇索引
  • 按照作用字段个数分为:单列索引和联合索引
  • 底层实现分为:B+Tree索引、B-Tree索引和Hash索引

3.1.普通索引

没有任何附加限制条件,只是用于提高查询效率。普通索引可以创建在任何数据类型上,其值是否唯一和非空由字段本身的完整性约束条件决定。

3.2.唯一索引

使用UNIQUE参数可以设置索引为唯一性索引,在创建唯一性索引时,限制该索引的值必须是唯一的。

3.3.聚簇(主键)索引

聚簇索引是InnoDB存储引擎中(MyISAM不支持聚簇索引)的一中数据存储方式,所有的用户记录都存储在了叶子结点上,数据和索引是一个文件(.idb) ,也就是:数据即索引。

image.png

聚簇索引的特点:

  • 记录主键值的大小进行页的排序:

    • 页内的记录按照主键的大小顺序排成一个单向链表
    • 各个页之间根据页内主键大小排成一个双向链表
    • 存放目录项的页分为不同层次,同一层次中各个页排成一个双向链表
  • B+树的叶子结点存储了完整的用户记录(所有列的值)

  • InnoDB存储引擎会自动根据主键创建聚簇索引,不需要手动创建。

  • MyISAM不支持聚簇索引。

  • 每个表只能有一个聚簇索引,一般是主键

  • 若没有定义主键,InnoDB会选择非空的唯一索引代替;若没有,InnoDB会隐式定义一个主键作为聚簇索引

  • 为了充分利用聚簇的特性,主键列尽量选用有序的ID

聚簇索引的优点:

  • 数据访问更快,因为将数据和索引保存在同一个B+树中。
  • 对于主键的排序查找范围查找速度非常快,节省I/O操作。

聚簇索引的缺点:

  • 插入速度严重依赖插入顺序,按照主键的顺序插入是最快的方式,否则会出现页分裂 (将当前页面分裂成两个页面,本页面的一些记录移动到新创建的页面) 。因此一般定义一个自增的列为主键。
  • 更新主键的代价很高,因为更新会导致该行移动。因此一般定义主键不可更新

InnoDB为什么采用B+树:

  • 数据库查询经常会出现非等值查询,哈希索引在这种情况下无法工作。
  • 相比于B树,B+树索引非叶子节点不存放数据,因此其内部结点相对B树更小,从而磁盘一次IO可以读取更多的索引数据,有效减少磁盘IO次数
  • 数据库查询经常会出现范围查询,B+树底层的叶子节点之间按照顺序排列,可以更有效的实现范围查询。

3.4.非聚簇索引(二级索引)

区别于聚簇索引,数据与索引分离

image.png

非聚簇索引特点:

  • 使用非主键字段作为数据页的排序规则。
  • 叶子结点中记录的不是完整的用户记录,而是作为索引的关键字段主键这两列的值(如果是联合索引则多列)。
  • 根据索引的关键字段来查询一条完整的用户记录时,需要通过两次索引查找:通过找到的主键值再到聚簇索引中进行回表,从而找到完整的记录。
  • 一张表可以存在多个非聚簇索引。

MyISAM索引方案:

image.png

  • MyISAM中所有索引都是非聚簇索引
  • 数据文件( .MYD)和索引文件分开存储( .MYI)。
  • B+树索引的叶子结点的data域存放的是对应.MYD文件中数据记录的地址
  • MyISAM中所有索引都有回表操作,且回表速度比InnoDB快,因为直接得到地址偏移量。

InnoDB索引与MySAM索引对比:

image.png