MySQL 索引

环境说明

MySQL8.0.16 image.png


索引概述

所有的 MySQL 类型都可以进行索引,对相关列使用索引是提高 SELECT 查询性能的最佳途径。MyISAM 和 InnoDB 都是使用 BTREE 作为索引,MySQL 5 不支持函数索引,但是支持 前缀索引
前缀索引顾名思义就是对列字段的前缀做索引,前缀索引的长度和存储引擎有关系。MyISAM 前缀索引的长度支持到 1000 字节,InnoDB 前缀索引的长度支持到 767 字节,索引值重复性越低,查询效率也就越高。
在 MySQL 中,主要有下面这几种索引

  • 全局索引(FULLTEXT):全局索引,目前只有 MyISAM 引擎支持全局索引,它的出现是为了解决针对文本的模糊查询效率较低的问题,并且只限于 CHAR、VARCHAR 和 TEXT 列。
  • 哈希索引(HASH):哈希索引是 MySQL 中用到的唯一 key-value 键值对的数据结构,很适合作为索引。HASH 索引具有一次定位的好处,不需要像树那样逐个节点查找,但是这种查找适合应用于查找单个键的情况,对于范围查找,HASH 索引的性能就会很低。默认情况下,MEMORY 存储引擎使用 HASH 索引,但也支持 BTREE 索引。
  • B-Tree 索引:B 就是 Balance 的意思,BTree 是一种平衡树,它有很多变种,最常见的就是 B+ Tree,它被 MySQL 广泛使用。
  • R-Tree 索引:R-Tree 在 MySQL 很少使用,仅支持 geometry 数据类型,支持该类型的存储引擎只有MyISAM、BDb、InnoDb、NDb、Archive几种,相对于 B-Tree 来说,R-Tree 的优势在于范围查找。

创建索引

索引可以在创建表的时候进行创建,也可以单独创建,下面采用单独创建的方式,在 emp 上创建前缀索引

  1. mysql> desc emp;
  2. +-------+-------------+------+-----+---------+-------+
  3. | Field | Type | Null | Key | Default | Extra |
  4. +-------+-------------+------+-----+---------+-------+
  5. | id | int(10) | YES | | NULL | |
  6. | name | varchar(20) | YES | | NULL | |
  7. +-------+-------------+------+-----+---------+-------+
  8. 2 rows in set (0.00 sec)
  9. mysql> create index idx_id on emp(id);
  10. Query OK, 0 rows affected (0.03 sec)
  11. Records: 0 Duplicates: 0 Warnings: 0
  12. mysql> desc emp;
  13. +-------+-------------+------+-----+---------+-------+
  14. | Field | Type | Null | Key | Default | Extra |
  15. +-------+-------------+------+-----+---------+-------+
  16. | id | int(10) | YES | MUL | NULL | |
  17. | name | varchar(20) | YES | | NULL | |
  18. +-------+-------------+------+-----+---------+-------+
  19. 2 rows in set (0.00 sec)

image.png
使用 explain 进行分析,可以看到 cxuan004 使用索引的情况

  1. mysql> explain select * from emp where id = '1%';
  2. +----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------+
  3. | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
  4. +----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------+
  5. | 1 | SIMPLE | emp | NULL | ref | idx_id | idx_id | 5 | const | 1 | 100.00 | NULL |
  6. +----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------+
  7. 1 row in set, 2 warnings (0.01 sec)

image.png

删除索引

如果不想使用索引,可以删除索引,索引的删除语法是

  1. mysql> drop index idx_id on emp;
  2. Query OK, 0 rows affected (0.01 sec)
  3. Records: 0 Duplicates: 0 Warnings: 0

image.png

索引设计原则

创建索引的时候,要尽量考虑以下原则,便于提升索引的使用效率。

  • 选择索引位置,选择索引最合适的位置是出现在 where 语句中的列,而不是 select 关键字后的选择列表中的列。
  • 选择使用唯一索引,顾名思义,唯一索引的值是唯一的,可以更快速的确定某条记录,例如学生的学号就适合使用唯一性索引,而学生的性别则不适合使用,因为不管搜索哪个值,都差不多有一半的行。
  • 为经常使用的字段建立索引,如果某个字段经常用作查询条件,那么这个字段的查询速度在极大程度上影响整个表的查询速度,因此为这样的字段建立索引,可以提高整个表的查询速度。
  • 不要过度索引,限制索引数目,索引的数目不是越多越好,每个索引都会占据磁盘空间,索引越多,需要的磁盘空间就越大。
  • 尽量使用前缀索引,如果索引的值很长,那么查询速度会受到影响,这个时候应该使用前缀索引,对列的某几个字符进行索引,可以提高检索效率。
  • 利用最左前缀,在创建一个 n 列的索引时,实际上是创建了 MySQL 可利用的 n 个索引。多列索引可以起到几个索引的作用,利用索引最左边的列来匹配行,这样的列称为最左前缀。
  • 对于使用 InnoDB 存储引擎的表来说,记录会按照一定的顺序保存。如果有明确的主键定义,那么会按照主键的顺序进行保存;如果没有主键,但是有唯一索引,那么就按照唯一索引的顺序进行保存。如果既没有主键又没有唯一索引,那么表中会自动生成一个内部列,按照这个列的顺序进行保存。一般来说,使用主键的顺序是最快的
  • 删除不再使用或者很少使用的索引