4 - 索引(上)- 常见索引模型以及 InnoDB 的索引

2020-05-13  本文已影响0人  天命_风流

关键字

索引,查询效率,B+树

0.什么是索引

索引就像是一本书的目录,可以提高数据的查询效率,如果没有索引,你很可能只能使用遍历的方式查询数据。

1.索引的常见模型

在《数据结构与算法之美》的专栏中,介绍了很多可以用于搜索的数据结构,包括:哈希表、有序数组、搜索树、跳表等。关于索引,我也写了一篇总结:具体算法8 - 索引的方方面面

在这里,我们简要的提一下哈希表、有序数组、搜索树这三种数据结构,具体如果有疑问,可以访问隔壁的《数据结构与算法之美》。

1.1散列表
散列表的底层是一个数组,它通过哈希函数计算数据所在的数组下标。散列表的查询速度很快,但是会面临哈希冲突的问题。下面给出一个例子,记录了四个人的身份证信息和姓名,并使用拉链法处理冲突: 4-哈希冲突.png

散列表的特点:

1.2有序数组
我们可以使用二分查找在有序数组中快速找到一个数据,同时它的范围查询性能也很优秀。依然是身份证查名字的例子: 4-有序数组.png

特点:

1.3搜索树
首先看一下二叉搜索树: 4-二叉搜索树.png

特点:

由于数据库的数据量很大,所以我们会将数据和索引都存到硬盘中。如果使用二叉搜索树,会多次访问磁盘,这会显著降低查找性能。

所以,为了加快查找,我们将二叉树扩展为 N 叉树,以加快查找。这也是 B+树 作为数据库索引的主要原因。具体可以看这里

2.InnoDB 的索引模型

在 InnoDB 中,所有索引都是使用 B+ 索引模型。

假设我们有如下的数据表:

mysql> create table T(
id int primary key, 
k int not null, 
name varchar(16),
index (k))engine=InnoDB;
表中 R1~R5 的 (ID,k)分别为 (100,1),(200,2),(300,3),(500,5),(600,6)。它的两个索引树如下: 4-InnoDB索引结构.png

注意:

两种索引的区别:

3.索引维护

随着数据的增加和删除,一个数据页内的索引可能过多(或过少),这时就需要进行索引的维护(具体过程依然建议看我之前的笔记):

有了上面的说明,我们看一个说法:

一些数据库建表规范有这样的描述:建表语句中一定要有自增主键

我们来分析这句话:

可以考虑使用业务字段直接做主键的情况:

  1. 只有一个索引
  2. 该索引是唯一索引
  3. 也就是典型的 KV 场景

小结

专栏作者的思考题
最后,我给你留下一个问题吧。对于上面例子中的 InnoDB 表 T,如果你要重建索引 k,你的两个 SQL 语句可以这么写:

alter table T drop index k;
alter table T add index(k);

如果你要重建主键索引,也可以这么写:

alter table T drop primary key;
alter table T add primary key(id);

我的问题是,对于上面这两个重建索引的作法,说出你的理解。如果有不合适的,为什么,更好的方法是什么?

解答:
通过两个 alter 语句重建索引 k,以及通过两个 alter 语句重建主键索引是否合理。

在评论区,有同学问到为什么要重建索引。我们文章里面有提到,索引可能因为删除,或者页分裂等原因,导致数据页有空洞,重建索引的过程会创建一个新的索引,把数据按顺序插入,这样页面的利用率最高,也就是索引更紧凑、更省空间。

这道题目,我给你的“参考答案”是:重建索引 k 的做法是合理的,可以达到省空间的目的。但是,重建主键的过程不合理。不论是删除主键还是创建主键,都会将整个表重建。所以连着执行这两个语句的话,第一个语句就白做了。这两个语句,你可以用这个语句代替 : alter table T engine=InnoDB。在专栏的第 12 篇文章《为什么表数据删掉一半,表文件大小不变?》中,我会和你分析这条语句的执行流程。


以上就是本节的全部内容

注:本文章的主要内容来自我对极客时间app的《MySQL实战45讲》专栏的总结,我使用了大量的原文、代码和截图,如果想要了解具体内容,可以前往极客时间

上一篇 下一篇

猜你喜欢

热点阅读