我们是光大科技智能云计算部智能化平台团队Devops项目组,专注于金融传统行业研发效能的提升和快速交付。通过自动化技术的应用,以及敏捷协同管理工具链的研发,助力金融传统行业Devops落地。团队拥有Devops领域经验丰富的研发工程师和专家,将不定期分享敏捷领域的原创文章,共同探索Devops落地最佳实践。
团队介绍
什么是数据库索引
首先让我们先看一下索引的定义:
中文网页版维基百科
索引(英语:Index):又称引得、通检、备检,是一本书籍的重要组成部分。它把书中的重要名词罗列出来,并给出它们相应的页码,方便读者快速查找该名词的定义和含义。
数据库索引:是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。
简单来说,索引就是为了提高数据的查询效率,就像书的目录一样,对于数据库而言,索引就是它的目录。
其实索引这个词并不是只有在数据库中会提到,让我们看看生活中的一个场景:
图书馆存了2000W本图书,要从中找到《java编程思想》,一本本查,要查到什么候去?
于是,图书管理员设计了一套规则:
(1)一楼放历史类,二楼放文学类,三楼放IT类…
(2)IT类,又分软件类,硬件类…
(3)软件类,又按照书名音序排序…
以便快速找到一本书。
与之类比,数据库存储了1000W条数据,要从中找到name=”zhangsan”的记录,一条条查,要查到什么时候去?
于是,跟图书管理员的方法类似,数据库索引就出现了,用于提升数据库的查找速度。
数据库索引加速查询的原理
提高查找速度的数据结构,常见的有两类:
(1)哈希,例如HashMap,查询/插入/修改/删除的平均时间复杂度都是O(1);
(2)树,例如平衡二叉搜索树,查询/插入/修改/删除的平均时间复杂度都是O(lg(n));
可以看到,不管是读请求,还是写请求,哈希类型的索引,都要比树型的索引更快一些,那为什么,索引结构要设计成树型呢?
索引设计成树形,和SQL的需求相关。对于这样一个单行查询的SQL需求:
select * from t where name=”zhangsan”;
确实是哈希索引更快,因为每次都只查询一条记录。
但是对于排序查询的SQL需求:
分组:group by
排序:order by
比较:<、>
…
哈希型的索引,时间复杂度会退化为O(n),而树型的“有序”特性,依然能够保持O(log(n)) 的高效率。
因此,InnoDB就选择了B+树作为索引的数据结构,也就是每?个索引在InnoDB??对应?棵B+树。
那现在让我们用几张图来更直观的感受下InnoDB 的索引模型吧。
假设,我们有?个主键列为ID的表,表中有字段k,并且在k上有索引。
这个表的建表语句是:
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),两棵树的示例示意图如下:
从图中不难看出,根据叶?节点的内容,索引类型分为主键索引和?主键索引。
主键索引的叶?节点存的是整?数据。在InnoDB?,主键索引也被称为聚簇索引(clustered index)。
?主键索引的叶?节点内容是主键的值。在InnoDB?,?主键索引也被称为?级索引(secondary index)。
根据上?的索引结构说明,我们来讨论?个问题:基于主键索引和普通索引的查询有什么区别?
如果语句是select * from T where ID=500,即主键查询?式,则只需要搜索ID这棵B+树;
如果语句是select * from T where k=5,即普通索引查询?式,则需要先搜索k索引树,得到ID的值为500,再到ID索引树搜索?次。这个过程称为回表。
索引优化
索引还有一些特性,基于这些特性的话,我们就可以结合实际中的场景对我们的sql语句进行优化,以此来提高sql的执行效率。
覆盖索引:
如果执?的语句是select ID from T where k between 3 and 5,这时只需要查ID的值,?ID的值已经在k索引树上了,因此可以直接提供查询结果,不需要回表。也就是说,在这个查询??,索引k已经“覆盖了”我们的查询需求,我们称为覆盖索引。由于覆盖索引可以减少树的搜索次数,显著提升查询性能,所以使?覆盖索引是?个常?的性能优化?段。
联合索引:
将表中多个字段联合起来建立索引,这样的好处是对于一些高频请求,可以利用覆盖索引的优势,不需要回表查整行的记录,减少语句的执行时间。
最左前缀原则:
B+树这种索引结构,可以利?索引的“最左前缀”,来定位记录。不只是索引的全部定义,只要满?最左前缀,就可以利?索引来加速检索。这个最左前缀可以是联合索引的最左N个字段,也可以是字符串索引的最左M个字符。所以,也就有了索引的复用能力,因为可以?持最左前缀,所以当已经有了(a,b)这个联合索引后,?般就不需要单独在a上建?索引了。
索引的缺点
有的同学看到这里可能会说,既然索引这么好,那我们就最好给每个字段都加索引,这样就大大提高了查询效率了。那未免就太过天真了,事物都有两面性,光说优点不说缺点那就是耍流氓。索引总体来说有以下几个缺点需要明确:
-
创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加;
-
索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大;
-
当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,降低了数据的维护速度。
总结
总的来说索引不是万能的,但是没有索引是万万不能的。享受了索引带来的优势,那么也要承担索引带来的问题,所以这对我们也是一个挑战。希望本文可以为各位看官带来一点点的收益。最后在送大家一些小编自己在使用索引中的一些小tips吧。我将tips放在了文章的评论区。欢迎大家积极讨论,将自己在使用索引中的一些经验也贴上来吧。
留言板
不用数据库非好汉,不懂索引也遗憾 留言区
往期回顾
– 开源云编排引擎Cloudify功能介绍
– 网络知识拓展小课堂–NQA及雾计算网络
– 一种视图与逻辑分离的前端项目研究与实践
– Vue3 Composition API介绍及实现原理分析
欢迎关注EBCloud!
作者|张国辉
原创文章,作者:EBCloud,如若转载,请注明出处:https://www.sudun.com/ask/33129.html