MySQL索引

0.前言

JavaGuide八股文

MySQL 索引详解open in new window

1.了解索引(INDEX)

索引是一种用于快速查询和检索数据的数据结构,其本质可以看成是一种排序好的数据结构。

索引的作用就相当于书的目录。打个比方: 我们在查字典的时候,如果没有目录,那我们就只能一页一页的去找我们需要查的那个字,速度很慢。如果有目录了,我们只需要先去目录里查找字的位置,然后直接翻到那一页就行了。

优点

  • 使用索引可以大大加快 数据的检索速度(大大减少检索的数据量), 这也是创建索引的最主要的原因。
  • 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。

缺点

  • 创建索引和维护索引需要耗费许多时间。当对表中的数据进行增删改的时候,如果数据有索引,那么索引也需要动态的修改,会降低 SQL 执行效率。
  • 索引需要使用物理文件存储,也会耗费一定空间。

但是,使用索引一定能提高查询性能吗?

大多数情况下,索引查询都是比全表扫描要快的。但是如果数据库的数据量不大,那么使用索引也不一定能够带来很大提升。

创建索引

## 在user表上对id属性添加索引user_index
CREATE INDEX user_index
ON user (id);

添加索引) 添加索引

## 修改表 在user表的添加对id属性的索引user_index
ALTER table user ADD INDEX user_index(id)

创建唯一索引) 创建唯一索引

CREATE UNIQUE INDEX user_index  ## UNIQUE关键字表示该索引是唯一索引
ON user (id);

删除索引) 删除索引

ALTER TABLE user
DROP INDEX user_index;  ## DROP语句删除索引 

2.索引底层数据结构

  • 底层使用B+树

为什么不使用Hash表:

  • hash表不支持范围查询与顺序查找,如下例子说明
SELECT * from table1 WHERE id < 500

如果在该例子内使用的是Hash表数据结构的话,那么我们需要对id处于1-499 内的索引进行一次Hash计算查找出对应的index,这样的话十分死板浪费资源时间。如果在该场景下使用B+树的话,直接遍历id < 500 的叶子节点就可以得到查询结果,这样的话就比较节省时间

B树与B+树

B树也称 B-树,全称为 多路平衡查找树 ,B+ 树是 B 树的一种变体。B 树和 B+树中的 B 是 Balanced (平衡)的意思

之间的区别:

MySQL索引_第1张图片
MySQL索引_第2张图片

  • B树是每一个节点都可以存储数据和key,B+树是只有叶子节点才会存储数据与key
  • B+树的非叶子节点之间会有一条引用链指向与其兄弟节点

3.主键索引与二级索引

主键索引

一张表只能有一个主键,该主键的值不能为null不能重复,根据该主键构建的索引就为主键索引

  • 在MySQL内的InnoDB的存储引擎内,如果用户没有显示的指明主键,没有主键,那么就会自动将表内有唯一索引并不允许存在null值的字段设置为主键并且创建主键索引。如果都没有,那么InnoDB 将会自动创建一个 6Byte 的自增主键。
if 存在主键
then 创建主键索引
else if 不存在主键
then 表内查找唯一索引并不允许null值的字段,设置为默认主键,创建主键索引
else then 自动创建一个6字节的自增主键

二级索引

  • 二级索引(Secondary Index)又称为辅助索引,是因为二级索引的叶子节点存储的数据是主键。也就是说,通过二级索引,可以定位主键的位置

  • 二级索引包括:唯一索引、前缀索引、普通索引

MySQL索引_第3张图片

4.聚簇索引与非聚簇索引

概念:

聚簇索引(聚集索引):索引结构和数据一起存放的索引,InnoDB 中的主键索引就属于聚簇索引。

非聚簇索引(非聚集索引):索引结构和数据分开存放的索引,二级索引(辅助索引)就属于非聚簇索引。MySQL 的 MyISAM 引擎,不管主键还是非主键,使用的都是非聚簇索引

各自索引的优缺点:(有点像数组与链表之间的区别)

  • 聚簇索引:
优点:
1.查询速度很快
2.排序查找与范围查找速度很快

缺点:
1.构建的数据需要是有序的数据
2.索引数据如果被修改的话,更新的代价比较大
  • 非聚簇索引:
优点:
1.更新代价比聚簇索引小

缺点:
1.依赖于有序的数据
2.有可能会出现二次查询(回调) (最大缺点)
回调:
当查到索引对应的指针或主键后,可能还需要根据指针或主键再到数据文件或表中查询。

5.怎样正确使用索引

选择合适的字段

  • 不为null的字段:对于数据为null的字段,数据库比较难优化,若该字段频繁被查询,那么可以赋值为0,1,true等代替null值
  • 比较频繁被查询的字段:索引的出现就是为了加快频繁查询字段的查询速度
  • 作为where条件查询的字段:建立了索引的字段,在where条件判断的时候会减少判断查询时间
  • 比较频繁需要排序的字段:索引会对字段进行排序,查询索引的字段,会加快排序的速度
  • 比较频繁作为连接的字段:经常用于连接的字段可能是一些外键列,对于外键列并不一定要建立外键,只是说该列涉及到表与表的关系。对于频繁被连接查询的字段,可以考虑建立索引,提高多表连接查询的效率

频繁更新的字段应该慎重建立索引

虽然索引能带来查询上的效率,但是维护索引的成本也是不小的。 如果一个字段不被经常查询,反而被经常修改,那么就更不应该在这种字段上建立索引了

限制每张表上的索引数目

  • 索引并不是越多越好,建议单张表索引不超过 5 个!索引可以提高效率同样可以降低效率。

  • 索引可以增加查询效率,但同样也会降低插入和更新的效率,甚至有些情况下会降低查询效率。

  • 因为 MySQL 优化器在选择如何优化查询时,会根据统一信息,对每一个可以用到的索引来进行评估,以生成出一个最好的执行计划,如果同时有很多个索引都可以用于查询,就会增加 MySQL 优化器生成执行计划的时间,同样会降低查询性能。

尽量建立联合索引而不是单列索引

因为索引是需要占用磁盘空间的,可以简单理解为每个索引都对应着一颗 B+树。如果一个表的字段过多,索引过多,那么当这个表的数据达到一个体量后,索引占用的空间也是很多的,且修改索引时,耗费的时间也是较多的。如果是联合索引,多个字段在一个索引上,那么将会节约很大磁盘空间,且修改数据的操作效率也会提升

注意避免亢余索引

冗余索引指的是索引的功能相同,能够命中索引(a, b)就肯定能命中索引(a) ,那么索引(a)就是冗余索引。如(name,city )和(name )这两个索引就是冗余索引,能够命中前者的查询肯定是能够命中后者的 在大多数情况下,都应该尽量扩展已有的索引而不是创建新索引

删除长期未使用的索引

冗余索引指的是索引的功能相同,能够命中索引(a, b)就肯定能命中索引(a) ,那么索引(a)就是冗余索引。如(name,city )和(name )这两个索引就是冗余索引,能够命中前者的查询肯定是能够命中后者的 在大多数情况下,都应该尽量扩展已有的索引而不是创建新索引

你可能感兴趣的:(数据库,mysql,数据库,sql)