一、啥是索引
一种高效获取数据的数据结构。通俗的说,数据库索引像一本书的目录,能加快数据的查询速度

一般来说索引本身很大,不可能全部存储在内存中,因此索引往往是存储在磁盘上的文件中的(可能存储在单独的索引文件中,也可能和数据一起存储在数据文件中)。

通常所说的索引,包括聚集索引、组合索引、唯一索引等等,默认都是使用 B+ 树结构组织的。
 

二、索引有啥优点和缺点
优点:
提高数据检索的效率,降低数据库的 IO 成本。
通过索引列对数据进行排序,降低了数据排序成本,降低 CPU 消耗。
(1)被索引的列会自动进行排序,包括单列索引和组合索引。
(2)如果按照索引列的顺序进行排序,比如对 order by 等语句来说,效率会提高。

缺点:
索引是占磁盘空间的,同时会降低更新表的效率。因为每次增删改操作,MySQL不仅要保存数据,还需要保存或者更新对应的索引文件。
 

三、常见的索引种类
主键索引
索引列中的值必须唯一,不允许有NULL。

普通索引
没有什么限制,允许在索引列中插入重复值和空值NULL。

唯一索引
索引列中的值必须唯一,但是允许为空值NULL。
(ps:其与主键索引区别:主键索引一定是唯一索引,但犯过老不行;一个表只能有一个主键索引,但可以有多个唯一索引;主键索引不允许为空,唯一索引可以;主键索引可以作为外键,唯一索引不行)

全文索引
只能在文本类型 CHAR,VARCHAR,TEXT 类型字段上创建全文索引。字段长度比较大时,如果创建普通索引,在进行 like 模糊查询时效率比较低,这时可以创建全文索引。MyISAM 和 InnoDB 中都可以使用全文索引。

联合索引
两个或多个列上的索引被称作联合索引,又叫复合索引。Mysql 从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分,即其需要遵循最左前缀匹配原则。比如你创建了三个字段的 idx_abc(a,b,c) 联合索引,相当于创建了(a)、(a,b)(a,b,c)三个索引,但是不支持使用(b,c)进行查找。
(ps:联合索引创建原则:把频繁使用的列、区分度高的列放在前面;当前索引频繁使用作为返回字段,这时可以考虑当前列是否可以加入到已经存在索引上构成联合索引,使其查询语句可以用到覆盖索引。)
 

四、Mysql 的 InnoDB 引擎的索引
1、主键索引(聚簇索引)
每个 InnoDB 表都有一个聚簇索引 ,聚簇索引使用 B+ 树构建,叶子节点存储的数据是整行记录,找到叶子节点也就找到了数据。一般情况下,聚簇索引等同于主键索引,当一个表没有创建主键索引时,InnoDB会自动创建一个 ROWID 字段来构建聚簇索引。InnoDB 创建索引的具体规则如下:

  • 在表上定义主键 PRIMARY KEY,InnoDB 将主键索引用作聚簇索引
  • 如果表没有定义主键,InnoDB 会选择第一个不为 NULL 的唯一索引列用作聚簇索引
  • 以上两个都没有,InnoDB 会使用一个 6 字节长整型的隐式字段 ROWID 字段构建聚簇索引。该 ROWID 字段会在插入新行时自动递增

mysql的表索引能重构吗 mysql索引结构优缺点_mysql


 

2、辅助索引

除聚簇索引之外的索引都是辅助索引。InnoDB 中辅助索引树中的叶子节点存储的是该行的主键值而不是整行记录。

在使用辅助索引检索时,会先在辅助索引树找到主键值,然后根据这个主键值再在聚簇索引(主键索引树)中搜索具体的行数据。这个过程叫回表

mysql的表索引能重构吗 mysql索引结构优缺点_数据库_02


 五、Mysql 的 MyISAM 引擎的索引

1、主键索引(非聚簇索引)

MyISAM 的数据文件和索引文件是分开存储的。其也使用 B+ 树构建索引树,但叶子节点中存储的是该行记录在磁盘中的地址。(也就是说找到叶子节点后还需要再从对应的地址中获取你想要的数据,而不是像聚簇索引那样直接就能获取到对应的数据)

mysql的表索引能重构吗 mysql索引结构优缺点_主键_03


 

2、辅助索引

MyISAM 的辅助索引和主键索引结构上没有什么区别,叶子节点存储的都是行记录的磁盘地址。只是主键索引的键值是唯一的,而辅助索引的键值允许重复。

 

六、啥是覆盖索引
覆盖索引并不是一种索引结构,它是一种常用的优化手段。我们知道,使用辅助索引时,只能先拿到主键值,然后再根据主键查询主键索引树获取到记录。但是有这样一种情况,假设有个 user 表,其 id 为主键,我们把 name 和 sex 两个字段建立了组合索引,然后有这样一个查询(select id,name,sex from user where name =‘zhangsan’)时,是不是意味着查询到组合索引的叶子节点后就可以获得了该语句要查的完整数据,然后就可以直接返回了,从而就没有了回表操作。这种情况即为覆盖索引。

怎么判断是不是用到了覆盖索引?
使用 explain,通过输出的 extra 列来判断,如果用到了索引覆盖查询,显示为 using index。

 

 

 

大佬,点个赞在走呗!

 

 

 

 

 

 

mysql的表索引能重构吗 mysql索引结构优缺点_mysql_04