前言

作者最近在学习数据库索引,故想通过写博客的方式记录学习情况,如有错误,敬请指出。


一、索引简介

1.1索引是什么

索引是一个单独的、存储在磁盘上的数据库结构,包含着对数据表里所有记录的引用指针。使用索引可以快速找出在某个或多个列中有一特定值的行,所有MySQL列类型都可以被索引,对相关列使用索引是提高查询操作速度的最佳途径。

1.2 索引的优劣势

优势:

  • 可以提高数据检索的效率,降低数据库的IO成本
  • 通过索引列对数据进行排序,降低了CPU的消耗

劣势:

  • 占磁盘空间
  • 当对表中的数据进行增加、删除和修改的时候,索引也要动态地维护,这样就降低了数据的维护速度。

1.3 何时使用索引

  • 当唯一性是某种数据本身的特征时,指定唯一索引。使用唯一索引需能确保定义的列的数据完整性,以提高查询速度。
  • 在频繁进行排序或分组(即进行group by或order by操作)的列上建立索引,如果待排序的列有多个,可以在这些列上建立组合索引。

二、索引的分类

2.1 单例索引

  • 常规索引:常规索引是MySQL中的基本索引类型,允许在定义索引的列中插入重复值和空值
  • 唯一索引要求索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一
  • 主键索引是一种特殊的唯一索引,不允许有空值

2.2 组合索引

  • 多个字段组合的索引,只有在查询条件中使用了这些字段的左边字段时,索引才会被使用。如果未使用中间的索引,后面的索引也会失效,使用组合索引时遵循最左前缀集合

索引及数据库安全 实验心得_学习

索引及数据库安全 实验心得_java_02


聚集索引选取规则:

  • 如果存在主键,主键索引就是聚集索引。
  • 如果不存在主键,将使用第一个唯一(UNIQUE)索引作为聚集索引。
  • 如果表没有主键,或没有合适的唯一索引,则InnoDB会自动生成一个rowid作为隐藏的聚集索
    引。

三、索引的使用

3.1 索引的基本命令

1.创建索引:

create index 索引名 on 表名(字段名(长度));
alter table 表名 add index 索引名(字段名(长度));

2.删除索引:

drop index 索引名 on 表名;

3.查看索引:

show index from 表名

3.2 判断索引是否生效

可以使用EXPLAIN语句查看索引是否正在使用。
explain select * from 表名 where 条件(条件需添加索引)

执行计划中各字段的含义:

索引及数据库安全 实验心得_数据库_03

3.3 避免索引失效

可以采用以下几种方式,来避免索引失效:

1.使用组合索引时,需要遵循“最左前缀”原则;

2.不在索引列上做任何操作,例如计算、函数、类型转换,会导致索引失效而转向全表扫描;

3.尽量使用覆盖索引(之访问索引列的查询),减少 select * 覆盖索引能减少回表次数;

4.MySQL在使用不等于(!=或者<>)的时候无法使用索引会导致全表扫描;

5.LIKE以通配符开头(%abc)MySQL索引会失效变成全表扫描的操作;
例如:
select * from company where companyName like ‘%江南皮革长’;
可以改为
select * from company where reverse(companyName) like reverse(‘%江南皮革长’);

6.字符串不加单引号会导致索引失效(可能发生了索引列的隐式转换);

7.当or连接的条件,左右两侧字段都有索引时,索引才会生效


四、索引实现原理(InnoDB)

在MySQL的索引结构中,选择的是B+Tree,那么什么是B+Tree呢?在说B+Tree前先介绍B-Tree

B-Tree(B树),B树是一种多叉路衡查找树,相对于二叉树,B树每个节点可以有多个分支,即多叉。
以一颗最大度数(max-degree)为5(5阶)的b-tree为例,那这个B树每个节点最多存储4个key,5
个指针:

索引及数据库安全 实验心得_学习_04

特点:

  • 5阶的B树,每一个节点最多存储4个key,对应5个指针。
  • 一旦节点存储的key数量到达5,就会裂变,中间元素向上分裂。
  • 在B树中,非叶子节点和叶子节点都会存放数据。

B+Tree是B-Tree的变种,我们以一颗最大度数(max-degree)为4(4阶)的b+tree为例,来看一
下其结构示意图:

索引及数据库安全 实验心得_学习_05


最终我们看到,B+Tree 与 B-Tree相比,主要有以下三点区别:

  • 所有的数据都会出现在叶子节点。
  • 叶子节点形成一个单向链表。
  • 非叶子节点仅仅起到索引数据作用,具体的数据都是在叶子节点存放的。

MySQL索引数据结构对经典的B+Tree进行了优化。在原B+Tree的基础上,增加一个指向相邻叶子节点
的链表指针,就形成了带有顺序指针的B+Tree,提高区间访问的性能,利于排序。

索引及数据库安全 实验心得_数据库_06


五、其他

5.1 回表查询

先到二级索引中查找数据,找到主键值,然后再到聚集索引中根据主键值,获取数据的方式,就称之为回表查询。

当我们执行下图查询语句时,具体过程如下:

索引及数据库安全 实验心得_mysql_07


1.由于是根据name字段进行查询,所以先根据name='Arm’到name字段的二级索引中进行匹配查
找。但是在二级索引中只能查找到 Arm 对应的主键值 10。

2. 由于查询返回的数据是所有字段,所以此时,还需要根据主键值10,到聚集索引中查找10对应的记录,最终找到10对应的行row。

3. 最终拿到这一行的数据,直接返回即可。

5.2 覆盖索引

覆盖索引是指 查询使用了索引,并且需要返回的列,在该索引中已经全部能够找到 。

索引及数据库安全 实验心得_索引及数据库安全 实验心得_08


索引及数据库安全 实验心得_java_09

索引及数据库安全 实验心得_学习_10

索引及数据库安全 实验心得_索引及数据库安全 实验心得_11

5.3 前缀索引

当字段类型为字符串(varchar,text,longtext等)时,有时候需要索引很长的字符串,这会让
索引变得很大,查询时,浪费大量的磁盘IO, 影响查询效率。此时可以只将字符串的一部分前缀,建
立索引,这样可以大大节约索引空间,从而提高索引效率。

create index idx_xxxx on table_name(column(n)) ;

索引及数据库安全 实验心得_mysql_12

总结

但愿吉祥