你还不知道什么是数据库的索引吗

346 阅读10分钟

这是我参与8月更文挑战的第9天,活动详情查看:8月更文挑战 | 作者:江夏

| CSDN:blog.csdn.net/qq_41153943

| 掘金:juejin.cn/user/651387…

| 知乎:www.zhihu.com/people/1024…

| GitHub:github.com/JiangXia-10…

本文大概1165字,建议阅读9分钟

一、什么是索引

在MySQL的官方文档里对于索引的定义是:索引(Index)是帮助MySQL高效获取数据的数据结构(有序)。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。

通过以上的官方定义,我们知道索引就是一种能够帮助我们从数据库中高效的查找数据的数据结构。对于索引最多的比较就是我们书的目录,如果我们想在一本书中查找到某个文章,最高效的方式就是通过目录,然后看这篇文章在第几页,而不是从前往后一页一页的翻。同样的对于没有建立索引的表,如果想查找某个数据也是通过遍历表的方式,这样的效率是很低的。如下图是两张数据表,一张是没有建立索引,一张表建立了索引。

图片

图1 没有建立索引的数据表

图片

图2 建立了索引的数据表

如图一所示,没有建立索引的数据表,如果需要查找一个数据需要从上到下的全局遍历整张表,那么如果查找第二列值为5的数据,就需要查找7次,显然效率是很低的。而图二对于这张表维护了一张如图所示的二叉查找树,二叉查找树的每个节点都分别包含了索引键值和一个指向对应数据记录物理地址的指针,这样就能够大大的加快对于数据的查找,比如同样还是查找第二列为5的数据,那么有二叉查找树作为索引的数据表的查找过程就是:

1、比较根节点和要查找的数据的值,5小于根节点35,那么就查找左子树;

2、同样的5小于左子树的节点15的值,那么继续查找左子树;

3、15的左子树的叶子节点的值和要查找的数据一致,那么该节点就是要查找的值,再看该节点指向的对应数据记录的物理地址。

以上对于第二列为5的数据的查找,只需要查找3次即可,效率大大的提升了。

索引是数据库中用来提高性能的最常用的工具,一般来说索引本身也很大,所以不可能全部存储在内存中。索引往往会以索引文件的方式存储在磁盘上。

二、索引的分类

索引根据其使用方式可以分为以下五类:

普通索引:仅加速查询。

唯一索引:加速查询 + 列值唯一(可以有null)。

主键索引:加速查询 + 列值唯一(不可以有null)+ 表中只有一个。

组合索引:多列值组成一个索引,专门用于组合搜索,其效率大于索引合并。

全文索引:对文本的内容进行分词,进行搜索。

三、索引的数据结构

索引是在数据库的存储引擎中实现的,而不是在服务器层实现的,所以每种存储引擎的索引都不一定完全相同,同样也不是索引的存储引擎都支持所有的索引类型。对于MySQL来说,它支持四种索引:

**BTree索引:**这是最为常见的索引类型,大部分的存储引擎都支持BTree索引。

**Hash索引:**Hash索引的使用场景比较简单,一般适用于不需要做排序、范围查询的需求。目前只有Memory存储引擎支持Hash索引。

**R-Tree索引:**又叫空间索引,它是MyISAM引擎的一种特殊的索引类型,主要应用于地理空间数据类型,所以使用的较少。

**Full—Text索引:**又叫全文索引,它也是MyISAM引擎的一种特殊的索引类型,但是InnoDB从MySQL5.6版本开始也支持全文索引,全文索引一般应用于全文搜索。

以上就是四种常见的索引类型,没有特别的指明,一般使用的索引都是指B+树(多路搜索树)数据结构的索引,它是BTree索引的一种变形。聚集索引、复合索引,前缀索引和唯一索引默认使用的都是B+树索引。

B+Tree和BTree的区别为:

1、n叉的B+Tree最多包含n个key,而BTree则最多可以包含n-1个key;

2、B+Tree的叶子节点保存所有的key的信息,并且按照key大小顺序排列;

3、B+Tree的所有的非叶子节点都可以看做是key的索引部分。

图片

图源网络,侵删

由于B+Tree只有叶子节点才保存key信息,查找任何的key都要从根节点走到叶子节点,所以相比较于BTree索引结构B+Tree的查询效率根据稳定。

在mysql数据中,对B+Tree进行了优化,在原B+Tree的基础之上,增加了一个指向相邻叶子节点的链表指针,形成了带有顺序指针的B+Tree,有提高了区间的访问性能。

图片

MySQL中的B+Tree索引结构(图源网络,侵删)

四、索引的优缺点

给数据表添加了索引确实能够大大的提高对于数据的访问性能,但是并不代表索引的数据表都应该添加索引,索引也有一定的缺点。所以索引的优缺点可以总结如下:

优点:

1、能够大大的提高数据的访问效率,减少数据库的IO操作;

2、通过索引列对数据进行排序,能够降低数据排序的成本,减少CPU的消耗。

缺点:

1、索引其实也是一张保存了主键和索引字段并且指向实体类记录的表,所以索引列也是需要占用一定的空间的。

2、虽然索引提高了数据的查询效率,但是同时也减低了表更新的速度,如果对于表进行插入,删除和更新操作,不仅要保存数据,还要保存一下索引文件每次更新添加了索引列的字段,因为更新会导致键值信息发生变化,所以还需要需要调整索引的索引信息。

五、索引的设计原则

上面分析了索引的优缺点,那么什么时候需要添加索引,什么时候不添加索引,添加索引需要遵循什么规则才能最大程度的提高性能呢/

索引的设计一般遵循以下的设计原则:

1.选择唯一性索引

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

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

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

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

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

4.限制索引的数目

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

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

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

6.尽量使用前缀来索引

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

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

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

选择索引的最终目的是为了使查询的速度变快。上面给出的原则是最基本的准则,但不能拘泥于上面的准则。应该根据应用的实际情况进行分析和判断,选择最合适的索引方式。

六、索引的基本语法

可以在创建数据表的同时创建索引,也可以在创建数据表之后随时新增索引。

1、创建索引

CREAT [UNIQUE|FULLTEXT|SPATIAL] INDEX Indexname
[USING index_type]
ON tableName(index_col_name,......)
给多个字段添加索引就是复合索引
index_col_name:colname[(length)][ASC|DESC]

比如:如果有一张student表,为该表的name字段创建索引:

create index idx_student_name on student(name)

2、查看索引

show index from table_name\G

3、删除索引

drop index index_name on table_name

4、alert命令

该语句添加一个主键,则表示索引值必须是唯一的,并且不能为NULL
alert table table_name add primary key(col_list)

这条语句创建索引的值必须是唯一的,但可以为NULL,并且NULL可以出现多次
alert talbe table_name add unique index_name(col_list)

添加普通索引,索引值可以出现多次
alert table table_name add index index_name(col_list)

该语句指定了全文索引,指定其他索引类似
alert table table_name add fulltext index_name(col_list)

七、结尾

以上就是数据库中关于索引的相关知识,本文主要介绍了什么是索引以及数据库中索引的分类、索引的设计原则以及索引的使用,索引是在日常的开发中经常需要使用的,熟练的掌握索引有助于我们开发中优化查询以及系统的设计,提高系统的性能!

有任何问题或者不正确的地方欢迎讨论指正!

相关推荐: