MySQL-索引

Posted 旷世奇才李先生

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL-索引相关的知识,希望对你有一定的参考价值。

有志者事竟成
文章持续更新,可以搜索【小奇JAVA面试】第一时间阅读,回复【资料】获取福利,回复【项目】获取项目源码,回复【简历模板】获取简历模板,回复【学习路线图】获取学习路线图。

文章目录


前言

索引是一种特殊的数据结构,可以用来快速查询数据库表中的特定记录。索引是提高数据库性能的重要方式。mysql中,所有的数据类型都可以被索引。MySQL的索引包括普通索引、唯一性索引、全文索引、单列索引、多列索引和空间索引等。

一、索引简介

索引由数据库表中一列或多列组合而成,其作用是提高对表中数据的查询速度。

1、索引的含义和特点

索引是创建在表上的,是对数据库表中一列或多列的值进行排序的一种结构。索引可以提高查询的速度。

通过索引,查询数据时可以不必读完记录的所有信息,而只是查询索引列。否则,数据库系统将读取每条记录的所有信息进行匹配。例如,索引相当于新华字典的音序表。如果要查“库”字,如果不使用音序,需要从字典的400页中逐页来找。但是,如果提取拼音出来,构成音序表。就只需要从10多页的音序表中直接查找。这样就可以大大节省时间。因此,使用索引可以很大程度上提高数据库的查询速度。这样有效的提高了数据库系统的性能。

不同的存储引擎定义了每个表的最大索引数和最大索引长度。所有存储引擎对每个表至少支持16个索引,总索引长度至少为256字节。有些存储引擎支持更多的索引数和更大的索引长度。索引有两种存储类型,包括B型树(BTREE)索引和哈希(HASH)索引。InnoDB和MyISAM存储引擎支持BTREE索引,MEMORY存储引擎支持HASH索引和BTREE索引,默认为前者。

索引有其明显的优势,也有其不可避免的缺点。

索引的优点是可以提高检索数据的速度,这是创建索引的最主要的原因;对于有依赖关系的子表和父表之间的联合查询时,可以提高查询速度;使用分组和排序子句进行数据查询时,同样可以显著节省查询中分组和排序的时间。

索引的缺点是创建和维护索引需要耗费时间,耗费时间的数量随着数据量的增加而增加;索引需要占用物理空间,每一个索引要占一定的物理空间;增加、删除和修改数据时,要动态的维护索引,造成数据的维护速度降低了。

因此,选择使用索引时,需要综合考虑索引的优点和缺点。

2、索引的分类

MySQL的索引包括普通索引、唯一性索引、全文索引、单列索引、多列索引和空间索引等。

1、普通索引

在创建普通索引时,不附加任何限制条件。这类索引可以创建在任何数据类型中,其值是否唯一和非空由字段本身的完整性约束条件决定。简历索引以后,查询时可以通过索引进行查询。例如,在student表的stu_id字段上建立一个普通索。查询记录时,就可以根据该索引进行查询。

2、唯一性索引

使用UNIQUE参数可以设置索引为唯一性索引。在创建唯一性索引时,限制该索引的值必须是唯一的。例如,在student表的stu_name字段中创建唯一性索引,那么stu_name字段的值就必需是唯一的。通过唯一性索引,可以更快速地确定某条记录。主键就是一种特殊唯一性索引。

3、全文索引

使用FULLTEXT参数可以设置索引为全文索引。全文索引只能创建在CHAR、VARCHAR或TEXT类型的字段上。查询数据量较大的字符串类型的字段时,使用全文索引可以提高查询速度。例如,student表的information字段是TEXT类型,该字段包含了很多的文字信息。在information字段上建立全文索引后,可以提高查询information字段的速度。MySQL数据库从3.23.23版开始支持全文索引,但只有MyISAM存储引擎支持全文检索。在默认情况下,全文索引的搜索执行方式不区分大小写。但索引的列使用二进制排序后,可以执行区分大小写的全文索引。

4、单列索引

在表中的单个字段上创建索引。单列索引只根据该字段进行索引。单列索引可以是普通索引,也可以是唯一性索引,还可以是全文索引。只要保证该索引只对应一个字段即可。

5、多列索引

多列索引是在表的多个字段上创建一个索引。该索引指向创建时对应的多个字段,可以通过这几个字段进行查询。但是,只有查询条件中使用了这些字段中第一个字段时,索引才会被使用。例如,在表中的id、name和sex字段上建立一个多列索引,那么,只有查询条件使用了id字段时该索引才会被使用。

6、空间索引

使用SPATIAL参数可以设置索引为空间索引。空间索引只能建立在空间数据类型上,这样可以提高系统获取空间数据的效率。MySQL中的空间数据类型包括GEOMETRY和POINT、LINESTRING和POLYGON等。目前只有MyISAM存储引擎支持空间检索,而且索引的字段不能为空值。对于初学者来说,这类索引很少会用到。

3、索引的设计原则

为了使索引的使用效率更高,在创建索引时,必须考虑在哪些字段上创建索引和创建什么类型的索引。

1、选择唯一性索引

唯一性索引的值是唯一的,可以更快速的通过该索引来确定某条记录。例如,学生表中学号是具有唯一性的字段。为该字段建立唯一性索引可以很快的确定某个学生的信息。如果使用姓名的话,可能存在同名的现象,从而降低查询速度。

2、为经常需要排序、分组和联合操作的字段建立索引

经常需要ORDER BY、GROUP BY、DISTINCT和UNION等操作的字段,排序操作会浪费很多时间。如果为其建立索引,可以有效地避免排序操作。

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

如果某个字段经常用来做查询条件,那么该字段的查询速度会影响整个表的查询速度。因此,为这样的字段建立索引,可以提高整个表的查询速度。

4、限制索引的数目

索引的数目不是越多越好。每个索引都需要占用磁盘空间,索引越多,需要的磁盘空间就越大。修改表时,对索引的重构和更新很麻烦。越多的索引,会使更新表变得很浪费时间。

5、尽量使用数据量少的索引

如果索引的值很长,那么查询的速度会受到影响。例如,对一个CHAR(100)类型的字段进行全文检索需要的时间肯定要比对CHAR(10)类型的字段需要的时间要多。

6、尽量使用前缀来索引

如果索引字段的值很长,最好使用值的前缀来索引。例如,TEXT和BLOG类型的字段,进行全文检索会很浪费时间。如果只检索字段的前面的若干个字符,这样可以提高检索速度。

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

表中的数据被大量更新,或者数据的使用方式被改变后,原有的一些索引可能不再需要。数据库管理员应当定期找出这些索引,将它们删除,从而减少索引对更新操作的影响。

二、创建索引

创建索引是指在某个表的一列或多列上建立一个索引,以便提高对表的访问速度。创建索引有3种方式,这3种方式分别是创建表的时候创建索引、在已经存在的表上创建索引和使用ALTER TABLE语句来创建索引。

1、创建表的时候创建索引

创建表时可以直接创建索引,这种方式最简单、方便。其基本形式如下:

create table 表名(
	属性名 数据类型 [完整性约束条件],
	属性名 数据类型 [完整性约束条件],
	...
	属性名 数据类型
	[UNIQUE | FULLTEXT |SPATIAL] INDEX | KEY
	[别名] (属性名1 [(长度)] [ASC | DESC])
);

其中,UNIQUE是可选参数,表示索引为唯一性索引;FULLTEXT是可选参数,表示索引为全文索引;SPATIAL也是可选参数,表示索引为空间索引;INDEX和KEY参数用来指定字段为索引的,两者选择其中之一就可以了,作用是一样的;“别名”是可选参数,用来给创建的索引取的新名称;“属性1”参数指定索引对应的字段的名称,该字段必须为前面定义好的字段;“长度”是可选参数,其指索引的长度,必须是字符串类型才可以使用;“ASC”和“DESC”都是可选参数,“ASC”参数表示升序排序,“DESC”参数表示降序排序。

1、创建普通索引

创建一个普通索引时,不需要加任何UNIQUE、FULLTEXT或者SPATIAL参数。

下面创建一个表名为index1的表,在表中的id字段上建立索引。SQL代码如下:


这个时候我们用show create table语句查看表的结构。显示如下:

结果可以看到,id字段上已经建立一个名为id的索引。使用EXPLAIN语句可以查看索引是否被使用,SQL代码如下:

上面结果显示,possible_keys和key处的值都为id。说明index1_id索引已经存在,而且已经开始起作用。

2、创建唯一性索引

创建唯一性索引时,需要使用UNIQUE参数进行约束。

下面创建一个表名为index2的表,在表中的id字段上建立名为index2_id的唯一性索引,且以升序的形式排序。SQL代码如下:


然后我们使用show create table语句查看表的结构。显示如下;


结果可以看到,id字段上已经建立了一个名为index2_id的唯一性索引。这里的id字段可以没有进行唯一性约束,也可以在该字段上成功创建唯一性索引。但是,这样的可能达不到提高查询速度的目的。

3、创建全文索引

全文索引只能创建在char、varchar或text类型的字段上。而且,现在只有MyISAM存储引擎支持全文索引。

下面创建一个表名为index3的表,在表中的info字段上建立名为index3_info的全文索引。SQL代码如下:


创建成功后我们用show create table语句查看表的结构。显示如下:


结果可以看到,info字段上已经建立了一个名为index3_info的全文索引。

4、创建单列索引

单列索引是在表的单个字段上创建索引。

下面创建一个表名为index4的表,在表中的subject字段上建立名为index4_st的单例索引。SQL代码如下:


创建成功后,我们使用show create table查看一下表结构


结果可以看到,subject字段上已经建立了一个名为index4_st的单例索引。细心的读者可能会发现,subject字段长度为20,而index4_st索引的长度只有10。这样做的目的还是为了提高查询速度。对于字符型的数据,可以不用查询全部信息,而只查询其前面的若干字符信息。

5、创建多列索引

创建多列索引是在表的多个字段上创建一个索引。

下面创建一个表名为index5的表,在表中的name和sex字段上建立名为index_ns的多列索引。SQL代码如下:

创建成功后,我们使用show create table查看表结构:


结果可以看到,name和sex字段上已经建立了一个名为index5_ns的单列索引。多列索引中,只有查询条件中使用了这些字段中第一个字段时,索引才会被使用。用EXPLAIN语句可以查看索引的使用情况。如果只是有name字段作为查询条件进行查询,显示结果如下:


结果显示,possible_key和key的值都是index5_ns。额外信息(Extra)显示正在使用索引。这说明使用name字段进行索引时,索引index5_nx已经被使用。如果只使用sex字段作为查询条件进行查询,显示结果如下:


此时的结果显示,possible_keys和key的值都为NULL。额外信息(Extra)显示正在使用Where条件查询,而未使用索引。

6、创建空间索引

创建空间索引时必须使用SPATIAL参数来设置。创建空间索引时,表的存储引擎必须是MyISAM类型。而且,索引字段必须有非空约束。

下面创建一个表名为index6的表,在表中space字段上建立名为index6_sp的空间索引。SQL代码如下:


创建成功后,我们使用show create table来查看表结构。


结果可以看到,space字段上已经建立了一个名为index6_sp的空间索引。值得注意的是,space字段是非空的,而且数据类型是geometry类型。这个类型是空间数据类型。空间类型包括geometry、point、linestring和polygon类型等。这些空间数据类型平时很少用到。

2、在已经存在的表上创建索引

在已经存在的表中,可以直接为表上的一个或几个字段创建索引。基本形式如下:

create [unique | fulltext | spatial] index 索引名 on 表名 (属性名 [(长度)] [ASC | DESC]);

其中,UNIQUE是可选参数,表示索引为唯一性索引;FULLTEXT是可选参数,表示索引为全文索引;SPATIAL也是可选参数,表示索引为空间索引;“INDEX”参数用来指定字段为索引的;“索引名”参数是给创建的索引取的新名称;“表名”参数是指需要创建索引的表的名称,该表必须是已经存在的,如果不存在,需要先创建;“属性名”参数指定索引对应的字段的名称,该字段必须为前面定义好的字段;“长度”是可选参数,其指索引的长度,必须是字符串类型才可以使用;ASC和DESC都是可选参数,ASC参数表示升序排列,DESC参数表示降序排列。

1、创建普通索引

下面在example0表中的id字段上建立名为index7_id的索引。SQL代码如下:


然后我们show create table语句查看一下表结构。


结果可以看到,example0表中的id字段上已经创建了一个名为index7_id的索引。这表示使用create index语句成功的在example0表上创建了普通索引。

2、创建唯一性索引

下面在index8表中的course_id字段上建立名为index8_id的唯一性索引。SQL代码如下:

create unique index index8_id on index8(course_id);

其中,index8_id为索引的名字,unique用来设置索引为唯一性索引;表index8中的course_id字段可以有唯一性约束,也可以没有唯一性约束。

3、创建全文索引

下面在index9表中的info字段上建立名为index9_info的全文索引。SQL代码如下:

create fulltext index index9_info on index9(info);

其中,FULLTEXT用来设置索引为全文索引;表index9的存储引擎必须是MyISAM类型;info字段必须为CHAR、VARCHAR和TEXT等类型。

4、创建单列索引

下面在index10表中的address字段上建立名为index10_addr的单列索引。address字段的数据类型为varchar(20),索引的数据类型为char(4)。SQL代码如下:

create index index10_addr on index10(address(4));

这样,查询时可以只查询address字段的前4个字符,而不需要全部查询。

5、创建多列索引

下面在index11表中的name和address字段上建立名为index11_na的多列索引。SQL代码如下:

create index index11_na on index11(name,address);

该索引创建好了以后,查询条件中必须有name字段才能使用索引。

6、创建空间索引

下面在index12表中的line字段上建立名为index12_line的多列索引。SQL代码如下:

create spatial index index12_line on index12(line);

其中,SPATIAL用来设置索引为空间索引;表index12的存储引擎必须是MyISAM类型;line字段必须为空间数据类型,而且是非空的。

3、用ALTER TABLE语句来创建索引

在已经存在的表上,可以通过alter table语句直接为表上的一个或几个字段创建索引。基本形式如下:

alter table 表名 add [unique | fulltext | spatial] index 索引名 (属性名 [(长度)] [ASC | DESC]);

其中的参数与上面的两种方式的参数是一样的。

1、创建普通索引

下面在example0表中的name字段上建立名为index13_name的索引。SQL代码如下:

alter table example0 add index index13_name(name(20));

2、创建唯一性索引

下面在index14表中的course_id字段上,建立名为index14_id的唯一性索引。SQL代码如下:

alter table index14 add unique index index14_id(course_id);

3、创建全文索引

下面在index15表中的info字段上建立名为index15_info的全文索引。SQL代码如下:

alter table index15 add fulltext index index15_info(info);

4、创建单列索引

下面在index16表中的address字段上建立名为index16_addr的单列索引。address字段的数据类型为varchar(20),索引的数据类型为char(4)。SQL代码如下:

alter table index16 add index index16_add(address(4));

5、创建多列索引

下面在index17表中的name和address字段上建立名为index17_na的多列索引。SQL代码如下:

alter table index17 add index index17_na(name,address);

6、创建空间索引

下面在index18表中的line字段上建立名为index18_line的多列索引。SQL代码如下:

alter table index18 add spatial index index18_line(line);

三、删除索引

删除索引是指将表中已经存在的索引删除掉。一些不再使用的索引会降低表的更新速度,影响数据库的性能。对于这样的索引,应该将其删除。本节将详细讲解删除索引的方法。

对应已经存在的索引,可以通过drop语句来删除索引。基本形式如下:

drop index 索引名 on 表名;

下面删除index1表的索引:

四、总结

这里的相关内容还没有整理完毕,文章后面持续更新,建议收藏。

文章中涉及到的命令大家一定要像我一样每个都敲几遍,只有在敲的过程中才能发现自己对命令是否真正的掌握了。

可以搜索【小奇JAVA面试】第一时间阅读,回复【资料】获取福利,回复【项目】获取项目源码,回复【简历模板】获取简历模板,回复【学习路线图】获取学习路线图。

以上是关于MySQL-索引的主要内容,如果未能解决你的问题,请参考以下文章

Mysql存储引擎索引原理详解

有关mysql索引

mysql——索引

MySQL笔记2.6索引

mysql数据库索引如何做?

mysql数据库索引和视图,触发器