数据库两大神器【索引和锁】(上)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 笔记

前言


索引和锁在数据库中可以说是非常重要的知识点了,在面试中也会经常会被问到的。

本文力求简单讲清每个知识点,希望大家看完能有所收获

声明:如果没有说明具体的数据库和存储引擎,默认指的是MySQL中的InnoDB存储引擎


一、索引


在之前,我对索引有以下的认知:

  • 索引可以加快数据库的检索速度
  • 经常进行INSERT/UPDATE/DELETE操作就不要建立索引了,换言之:索引会降低插入、删除、修改等维护任务的速度。
  • 索引需要占物理和数据空间
  • 了解过索引的最左匹配原则
  • 知道索引的分类:聚集索引和非聚集索引
  • Mysql支持Hash索引和B+树索引两种

看起来好像啥都知道,但面试让你说的时候可能就GG了:

  • 使用索引为什么可以加快数据库的检索速度啊?
  • 为什么说索引会降低插入、删除、修改等维护任务的速度。
  • 索引的最左匹配原则指的是什么?
  • Hash索引和B+树索引有什么区别?主流的使用哪一个比较多?InnoDB存储都支持吗?
  • 聚集索引和非聚集索引有什么区别?
  • ……..


1.1聊聊索引的基础知识


首先Mysql的基本存储结构是(记录都存在页里边):

1.jpg2.jpg

  • 各个数据页可以组成一个双向链表
  • 每个数据页中的记录又可以组成一个单向链表
  • 每个数据页都会为存储在它里边儿的记录生成一个页目录,在通过主键查找某条记录的时候可以在页目录中使用二分法快速定位到对应的槽,然后再遍历该槽对应分组中的记录即可快速找到指定的记录
  • 其他列(非主键)作为搜索条件:只能从最小记录开始依次遍历单链表中的每条记录

所以说,如果我们写select * from user where username = 'Java3y'这样没有进行任何优化的sql语句,默认会这样做:

  • 定位到记录所在的页
  • 需要遍历双向链表,找到所在的页
  • 从所在的页内中查找相应的记录
  • 由于不是根据主键查询,只能遍历所在页的单链表了

很明显,在数据量很大的情况下这样查找会很慢


1.2索引提高检索速度


索引做了些什么可以让我们查询加快速度呢?

其实就是将无序的数据变成有序(相对)

3.jpg

要找到id为8的记录简要步骤:

4.jpg

很明显的是:没有用索引我们是需要遍历双向链表来定位对应的页,现在通过“目录”就可以很快地定位到对应的页上了!

其实底层结构就是B+树,B+树作为树的一种实现,能够让我们很快地查找出对应的记录。

参考资料:


1.3索引降低增删改的速度


B+树是平衡树的一种。

平衡树:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

如果一棵普通的树在极端的情况下,是能退化成链表的(树的优点就不复存在了)

5.jpg

B+树是平衡树的一种,是不会退化成链表的,树的高度都是相对比较低的(基本符合矮矮胖胖(均衡)的结构)【这样一来我们检索的时间复杂度就是O(logn)】!从上一节的图我们也可以看见,建立索引实际上就是建立一颗B+树。

  • B+树是一颗平衡树,如果我们对这颗树增删改的话,那肯定会破坏它的原有结构
  • 要维持平衡树,就必须做额外的工作。正因为这些额外的工作开销,导致索引会降低增删改的速度

B+树删除和修改具体可参考:


1.4哈希索引


除了B+树之外,还有一种常见的是哈希索引。

哈希索引就是采用一定的哈希算法,把键值换算成新的哈希值,检索时不需要类似B+树那样从根节点到叶子节点逐级查找,只需一次哈希算法即可立刻定位到相应的位置,速度非常快

  • 本质上就是把键值换算成新的哈希值,根据这个哈希值来定位

6.jpg

看起来哈希索引很牛逼啊,但其实哈希索引有好几个局限(根据他本质的原理可得):

  • 哈希索引也没办法利用索引完成排序
  • 不支持最左匹配原则
  • 在有大量重复键值情况下,哈希索引的效率也是极低的---->哈希碰撞问题。
  • 不支持范围查询

参考资料:


1.5InnoDB支持哈希索引吗?


主流的还是使用B+树索引比较多,对于哈希索引,InnoDB是自适应哈希索引的(hash索引的创建由InnoDB存储引擎引擎自动优化创建,我们干预不了)!

7.jpg

参考资料:


1.6聚集和非聚集索引


简单概括:

  • 聚集索引就是以主键创建的索引
  • 非聚集索引就是以非主键创建的索引

区别:

  • 聚集索引在叶子节点存储的是表中的数据
  • 非聚集索引在叶子节点存储的是主键和索引列
  • 使用非聚集索引查询出数据时,拿到叶子上的主键再去查到想要查找的数据。(拿到主键再查找这个过程叫做回表)

非聚集索引也叫做二级索引,不用纠结那么多名词,将其等价就行了~

非聚集索引在建立的时候也未必是单列的,可以多个列来创建索引。

  • 此时就涉及到了哪个列会走索引,哪个列不走索引的问题了(最左匹配原则-->后面有说)
  • 创建多个单列(非聚集)索引的时候,会生成多个索引树(所以过多创建索引会占用磁盘空间)

8.jpg

在创建多列索引中也涉及到了一种特殊的索引-->覆盖索引

  • 我们前面知道了,如果不是聚集索引,叶子节点存储的是主键+列值
  • 最终还是要“回表”,也就是要通过主键查找一次。这样就会比较慢
  • 覆盖索引就是把要查询出的列和索引是对应的,不做回表操作!

比如说:

  • 现在我创建了索引(username,age),在查询数据的时候:select username , age from user where username = 'Java3y' and age = 20
  • 很明显地知道,我们上边的查询是走索引的,并且,要查询出的列在叶子节点都存在!所以,就不用回表了~
  • 所以,能使用覆盖索引就尽量使用吧~


1.7索引最左匹配原则


最左匹配原则

  • 索引可以简单如一个列(a),也可以复杂如多个列(a, b, c, d),即联合索引
  • 如果是联合索引,那么key也由多个列组成,同时,索引只能用于查找key是否存在(相等),遇到范围查询(>、<、between、like左匹配)等就不能进一步匹配了,后续退化为线性查找。
  • 因此,列的排列顺序决定了可命中索引的列数

例子:

  • 如有索引(a, b, c, d),查询条件a = 1 and b = 2 and c > 3 and d = 4,则会在每个节点依次命中a、b、c,无法命中d。(很简单:索引命中只能是相等的情况,不能是范围匹配)


1.8=、in自动优化顺序


不需要考虑=、in等的顺序,mysql会自动优化这些条件的顺序,以匹配尽可能多的索引列。

例子:

  • 如有索引(a, b, c, d),查询条件c &gt; 3 and b = 2 and a = 1 and d < 4`与`a = 1 and c > 3 and b = 2 and d < 4`等顺序都是可以的,MySQL会自动优化为`a = 1 and b = 2 and c > 3 and d &lt; 4,依次命中a、b、c。
相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
1月前
|
SQL 数据库 数据库管理
【SQL server】玩转SQL server数据库:第三章 关系数据库标准语言SQL(一)模式、表、索引与视图
【SQL server】玩转SQL server数据库:第三章 关系数据库标准语言SQL(一)模式、表、索引与视图
68 11
|
14天前
|
存储 机器学习/深度学习 搜索推荐
深入解析矢量数据库的数据模型与索引机制
【4月更文挑战第30天】本文深入探讨了矢量数据库的数据模型和索引机制。向量数据库以高维向量表示数据,采用稀疏或密集向量形式,并通过数据编码和组织优化存储与检索。索引机制包括基于树的(如KD-Tree和Ball Tree)、基于哈希的(LSH)和近似方法(PQ),加速相似性搜索。理解这些原理有助于利用矢量数据库处理大规模高维数据,应用于推荐系统、图像搜索等领域。随着技术发展,矢量数据库将扮演更重要角色。
|
6天前
|
存储 关系型数据库 分布式数据库
数据库索引回表困难?揭秘PolarDB存储引擎优化技术
PolarDB分布式版存储引擎采用CSM方案均衡资源开销与可用性。
数据库索引回表困难?揭秘PolarDB存储引擎优化技术
|
15天前
|
关系型数据库 数据库 索引
关系型数据库使用索引
关系型数据库使用索引
25 1
|
16天前
|
关系型数据库 大数据 数据库
关系型数据库索引优化
关系型数据库索引优化是一个综合的过程,需要综合考虑数据的特点、查询的需求以及系统的性能要求。通过合理的索引策略和技术,可以显著提高数据库的查询性能和整体效率。
22 4
|
17天前
|
数据库 UED 索引
构建高效的数据库索引:提升查询性能的关键技巧
本文将深入探讨数据库索引的设计和优化,介绍如何构建高效的数据库索引以提升查询性能。通过学习本文,读者将掌握数据库索引的原理、常见类型以及优化策略,从而在实际应用中提升数据库查询效率。
|
18天前
|
关系型数据库 MySQL 数据库
【MySQL】数据库索引(简单明了)
【MySQL】数据库索引(简单明了)
|
22天前
|
SQL 存储 关系型数据库
数据库开发之事务和索引的详细解析
数据库开发之事务和索引的详细解析
16 0
数据库开发之事务和索引的详细解析
|
25天前
|
SQL Oracle 安全
Oracle数据库中的事务和锁
【4月更文挑战第19天】Oracle数据库的事务和锁是确保数据完整性和并发控制的核心机制。事务遵循ACID原则,保证操作的原子性、一致性、隔离性和持久性。通过COMMIT或ROLLBACK来管理事务更改。锁包括共享锁(读)、排他锁(写)、行级锁和表级锁,用于控制并发访问。自动锁机制在DML操作时生效,防止数据冲突。事务和锁共同维护数据库的稳定和安全。
|
26天前
|
关系型数据库 MySQL 数据库
【后端面经】【数据库与MySQL】12|数据库锁:明明有行锁,怎么突然就加了表锁?
【4月更文挑战第15天】在MySQL的InnoDB引擎中,锁通过索引实现,主要锁定叶子节点。查询使用哪个索引,就锁哪个;无索引时锁全表。若查询值不存在,InnoDB会构造临键锁阻止插入。锁在事务结束(Rollback或Commit)时释放。乐观锁在尝试更新时检查数据变化,适合读多写少场景,悲观锁一开始就加锁,适用于写多读少。InnoDB支持行锁和表锁,行锁依赖索引。共享锁允许多个线程加同类型锁,排它锁则独占。
43 1