MYSQL索引以及索引的底层原理

1、索引分类

索引:索引是创建在表上,是对数据库中的一列或者多列的值进行排序的一种结果。

优点:提高查询的效率

缺点:索引并非是越多越好,过多的索引会导致CPU使用居高不下,由于数据的改动引起索引文件的改动,过多的磁盘IO造成CPU负载过高。

普通索引:没有任何的限制条件,可以给任何类型的字段创建普通索引

唯一性索引:使用unqiue修饰的字段,值不会重复,主键索引隶属唯一性索引

主键索引:使用primray key修饰的字段,会自动创建索引

多列索引:在表的多个字段上创建索引

全文索引:使用FULLTEXT参数可以设置全文索引,只支持char、varchar和text类型的字段,常用于数据量较大的字符类型上,只有MYISAM储存引擎支持

2、索引的创建和删除

2.1 在创建表时指定索引字段

index(属性名):指定当前的属性名为索引

create table Student(ID INT,
                     Name varchar(10),
                     index(ID));

 2.2 在已经创建表上添加索引

create[unique/fulltext/spatial] index 索引名(index) on table_name(属性);

create index id on Student(ID);

2.3 删除索引

drop index 索引名 on 表名;

drop index id on Student;

3、索引的执行过程

首先创建一个表,然后在表中插入基础的数据;接着在某一条件下进行查询

通过explain分析SQL执行过程,将表中的某一个字段设置为索引,重复查询的过程(在某一条件下进行查询通过explain分析SQL执行过程)

创建一个Student表,表里的字段分别为:

Student(SID,Sname,Sage,Ssex)

--SID 学生编号,Sname 学生姓名,Sage 年龄,Ssex 学生性别

插入基本数据:

select * from Student;

+-----+----------+------+------+

| SID | Sname    | Ssex | Sage |

+-----+----------+------+------+

|   1 | zhaolei  | nan  |   20 |

|   2 | qiandian | nan  |   20 |

|   3 | sunfen   | nan  |   21 |

|   4 | wulan    | nv   |   18 |

+-----+----------+------+------+

数据库里插入了四条数据:

查询姓名为"zhaolei"的数据记录,通过explain分析SQL执行过程

mysql> explain select * from Student where Sname = 'zhaolei'\G
*************************** 1. row ***************************

           id: 1

  select_type: SIMPLE

        table: Student

         type: ALL

possible_keys: NULL

          key: NULL

      key_len: NULL

          ref: NULL

         rows: 4

        Extra: Using where

1 row in set (0.01 sec)

运行结果的参数说明:

(1)id列:是在QEP中展示的表的连续引用

(2)select_type列:提供了各种表示table列引用的使用方式的类型。最常见的值包括SIMPLE、PRIMARY、DERIVED 和UNION。其他可能的值还有UNION RESULT、DEPENDENT SUBQUERY、DEPENDENT UNION、UNCACHEABLE UNION 以及UNCACHEABLE QUERY。

SIMPLE对于不包含子查询和其他复杂语法的简单查询,这是一个常见的类型。

PRIMARY这是为更复杂的查询而创建的首要表(也就是最外层的表)。这个类型通常可以在DERIVED 和UNION 类型混合使用时见到。

DERIVED当一个表不是一个物理表时,那么就被叫做DERIVED。

DEPENDENT SUBQUERY这个select-type 值是为使用子查询而定义的。

UNION这是UNION 语句其中的一个SQL 元素。

(3)table列:是EXPLAIN命令输出结果中的一个单独行的唯一标识符。这个值可能是表明、表的别名或者一个为查询产生临时表的标识符,如派生表、子查询或集合。

(4)type列:type列代表QEP中指定的表使用的连接方式。

(5)possible_keys 列:指出优化器为查询选定的索引。

(6)key列:指出优化器选择使用的索引。

(7)key_len 列:定义了用于SQL 语句的连接条件的键的长度。

(8)ref 列:可以被用来标识那些用来进行索引比较的列或者常量。

(9) rows 列:提供了试图分析所有存在于累计结果集中的行数目的MySQL 优化器估计值。

(10)Extra 列:提供了有关不同种类的MySQL 优化器路径的一系列额外信息。Extra 列可以包含多个值,可以有很多不同的取值,并且这些值还在随着MySQL 新版本的发布而进一步增加。

       可以通过possible_keys、key没有用到索引,并且通过rows: 4可以看出直接全表扫描一遍才找到"zhaolei"的信息,假设表中4百万数据,那么查找"zhaolei"同学就需要扫描4百万的数据,效率比较低。

以名字创建索引

create index idx_name on Student (Sname);

mysql> explain select * from Student where Sname = 'zhaolei'\G

*************************** 1. row ***************************

           id: 1

  select_type: SIMPLE

        table: Student

         type: ref

possible_keys: idx_name

          key: idx_name

      key_len: 27

          ref: const

         rows: 1

        Extra: Using index condition

1 row in set (0.01 sec)

注意:这次查询"zhaolei"同学的信息,只在表中查询一行数据就可以得到(rows: 1)

explain命令,可以查看SQL执行计划,分析SQL语句是否正确使用索引

4、索引的底层原理

       MYSQL支持两种索引,B-数索引和哈希索引,这两种索引的查询效率高。

       MYSQL存储引擎默认的是INNODB存储引擎,基于B-树(MYSQL实际采用是B+树)结构。

       B-树是一种M阶平衡树,叶子节点都在同一层,由于每一阶存储的数据量比较大,索引的整个B-树的层数是比较低的,基本上不超过三层。

       由于磁盘的读取按照block块操作,(内存按照page页来操作的),因此B-树的节点大小一般设置和磁盘的大小一致,这样读取一个B-树的节点,就可以通过一次磁盘IO操作将数据全部读取/存储下来,所以使用B-树作为索引的时候,磁盘IO的次数是最少的(MYSQL读写效率,主要集中在磁盘IO上)

为什么MYSQL最终使用B+树而不是B-树,它们在存储结构上有什么不同?(重点)

1、B-树的每一个节点,存储的是关键字和对应的数据地址,而B+树的非叶子节点存储关键字,因此B+树的每一个非叶子节点存储的关键字数量远远多于B-树,B+树叶子节点存储关键字和数据

因此:从树的高度来说,B+树的高度要小于B-树,使用磁盘的次数少

2、B-树由于每一个节点存储关键字和数据,因此离根节点近的数据查询比较快,离根节点比较远的数据,查询就比较慢

     B+树上所有的数据都存储在叶子节点上,因此B+树查询关键字,找到对应数据的时间上是比较均匀的,没有快慢之分

3、B-树如果做区间查找,遍历的节点比较多的,B+树所有的叶子节点被连接成有序链表结构,因此做整表遍历和区间查找是非常容易的

       哈希索引是由哈希表实现,哈希表无法对数据做到排序,因此无法做区间查找,效率非常低,需要查询整个哈希结构。

主键索引、辅助索引、聚集索引、非聚集索引

主要研究的存储引擎是MyISAM和InNoDB存储引擎的索引结构

1、MyISAM存储引擎-主键索引

       MyISAM引擎使用B+树作为索引结构、叶节点的data域存放的是数据记录地址,下图四MyISAM主键索引的原理图:

2、MyISAM存储引擎-辅助索引

       MyISAM中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求key是唯一的,而辅助索引的key可以重复,如果给其他字段创建辅助索引,结构图如下:

       根据上面两张图,首先按照B+Tree搜索算法搜索索引,如果指定的key存在,则取出其data域的值,然后以data域的值为地址,读取相应数据记录。

       可以看出:MYISAM存储引擎,索引结构叶子节点存储关键字和数据地址,也就是说索引关键字和数据没有在一起存放,体现在磁盘上,就是索引在一个文件存储,数据在另一个文件存储。

       MYISAM的索引方式也叫做非聚集索引,之所以这么称呼为了与InNoDB的聚集索引区分

3、INNODB存储引擎-主键索引

       INNODB存储引擎的主键索引,叶子节点中,索引关键字和数据是在一起存放的,如图:

 

       可以看到,索引关键字和数据一起存储在叶子节点上。

4、INNODB存储引擎-辅助索引

       INNODB的辅助索引,叶子节点上存放的是索引关键字和对应的主键,如图:

 

       辅助索引的B+树,先根据关键字找到对应的主键,再去主键索引树上找到对应的行记录数据。

       从索引树上可以看到,INNODB的索引关键字和数据都是在一起存放的,体现在磁盘存储上。

       INNODB的索引树叶子节点包含了完整的数据记录,这种索引叫做聚集索引。因为INNODB的数据文件本身要按照主键聚集,所以INNODB要求表必须有主键(MYISAM可以没有),如果没有显示指定,则MYISAM系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MYSQL自动为INNODB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整型索引的设计原则。

       可以看出,使用索引是有能提高查询效率,但是给表创建过多的索引,效率反而会降低,因此在设计表索引的时候,需要遵循以下的设计原则

1、给区分度高的字段创建索引                    eg:学号、省份证号

2、给经常需要排序,分组和多表联合操作的字段创建索引

3、经常作为查询条件的字段创建索引

4、索引的数据不宜过多

5、使用数据量少的索引(如前缀索引,主要针对字符串索引,字符串类型尽量创建前缀索引)

6、对于多列索引,优先指定最左边的列集

7、删除不在使用或者很少使用的索引

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值