mysql 系列:搞定索引

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 索引是数据库里重要的组成部分,也是提高查询效率必备的知识点。本文将会介绍索引作用、索引类型、索引优化以及索引底层结构,也算是对索引知识的一次归纳。

摘要

索引是数据库里重要的组成部分,也是提高查询效率必备的知识点。本文将会介绍索引作用索引类型索引优化以及索引底层结构,也算是对索引知识的一次归纳

一、索引介绍

什么是索引?

数据库是用来存储与读取数据的,如何在这庞大的数据中查询我们想要的那一行呢?最简单的办法便是扫描整个数据表,一一对比。然而这样效率太低了。

如果我们有类似字典的功能,在查询某行数据前,先到字典里定位到行位置,再根据行位置找到具体数据,是否能更快呢?是的,索引就是这么设计的。

一般的,我们往表里插入某一行数据时,总会有额外的信息来定位到这一行。这个信息可能是一个指针地址,也可能是一个主键标识

在拿到这一行的定位信息后,就可以将列数据和定位信息做关联了。下次想查找这个字段列所对应的行数据时,就可以先到关联信息里搜索,拿到定位信息后直接查找即可。这就是索引,存储了列和定位信息,这定位信息也可以理解指向数据记录的引用指针

需要注意的是,索引是由存储引擎这个模块来实现的,不同的存储引擎有不同的实现方式。像 innodb 的主键就包含了行数据,找到了主键,也就找到了数据。

索引的分类

在数据库里,索引有好多种。我们可以从下面几方面来分类归纳。

从数据结构划分:B+ 树、hash 索引、全文索引
从物理结构划分:聚集索引、非聚集索引
从逻辑用户划分:主键、唯一索引、复合索引、普通单列索引

其中, B+ 树、 hash 索引、全文索引将会在后面具体介绍其底层结构,我们来看看其他的索引:

聚集索引:该索引除了存储索引信息还存储了行数据,像刚刚提到的主键就是。找到它也就意味找到数据了。并且它的排序直接对应了物理存储顺序。

非聚集索引:该索引除了存储索引信息还存储了定位到数据记录的信息,需要根据这个信息再做一次查询,才能获取到数据,并且它的排序是逻辑上,不是物理存储顺序。

主键:唯一地标识表中一条记录的索引,不能有 NULL 值。在 InnoDB 里,主键就是聚集索引。

唯一索引:索引所对应的列值里是不能有重复值的,允许有 NULL 值。像刚刚提到的主键是不允许有 NULL 值的。

复合索引:有多列组合在一起的索引,但只能按最左原则查找,即第一列字段才能被索引查找,后面只是作为附带信息存放着。主要是为了找到索引后,不需要再去行数据里捞数据,直接从索引里提取字段信息即可。

普通单列索引:没有什么限制条件的索引列。

索引的缺点

引入索引,并不总意味着高效,它是需要付出代价维护的。每当有数据需要添加更新时,都得更新对应的索引,这是额外的性能开销,甚至有可能有出现死锁。

另外,索引是需要占用磁盘空间的,不能无限制的添加索引,要有针对性的建索引。

二、索引的使用

使用原则

索引之所以那么快,是因为我们将平时查询频率较高的字段单独维护了起来。当我们有多个查询选项,多个查询条件就不一定能发挥作用了,所以索引的使用是有注意事项的,下面总结了一些:

  • where 里最经常用到的查询字段才建索引,能利用主键 id,就用主键 id 来增删改查
  • 按最左匹配原则,将多个单列索引改为复合索引,减少维护量
  • 尽量挑选择度高,也就是重复率低的列作为索引,像性别这种列就不适合了,会在 B+ 树里做多层次多范围的搜索,还不如全表扫描呢
  • 查找时,不对索引列做函数计算,否则不能使用到索引
  • 查询条件尽量用 union 来取代 or
  • like 用法: ‘列%’ 这样还是可以用到索引的,'%列%' 就不行了
  • IS NULL,IS NOT NULL 是用不到索引的
  • 在 order by,group by 里尽量使用索引字段
  • join 的 on 条件里尽量使用索引字段

性能分析

当我们使用了索引后,又如何知道它有没有使用到索引呢?我们可以借助执行计划来分析,执行计划是 mysql 根据我们的查询语句进行一系列的分析后得到的优化方案。我们可以通过执行计划来获取执行过程。

执行计划的获取:

explain select 语句

执行计划

涉及的字段含义如下:

  • id: 该 SELECT 标识符
  • select_type: 该 SELECT 类型
  • table: 输出行的表
  • partitions: 匹配的分区
  • type: 联接类型
  • possible_keys: 可供选择的可能索引
  • key: 实际选择的索引
  • key_len: 所选密钥的长度
  • ref: 与索引比较的列
  • rows: 估计要检查的行数
  • filtered: 按表条件过滤的行百分比
  • Extra: 附加信息

其中,有个 type 字段,它的含义大概如下:

  • eq_ref: 使用到了 UNIQUE 或 PRIMARY KEY 索引
  • ref: 显示索引的哪一列被使用了
  • ref_or_null: 对 Null 进行了索引优化
  • range: 索引范围检索
  • index: 索引扫描
  • unique_subquery: 使用了 in 子查询,里面涉及了主键字段
  • index_subquery: 使用了 in 子查询,里面涉及了非唯一索引
  • fulltext: 全文索引
  • all: 全表扫描数据

从上面大概就能分析出索引的使用情况了,如果是 all,那就是没有用到索引了。

索引的的底层

前面提到过索引的种类时,细分了 B+ 树、hash 索引、全文索引这三类。现在我们来具体看下对应的底层结构吧。

B+树

在 B+ 树之前还有二叉搜索树B 树,我们来一步一步演化,看看有什么不同,先来看二叉搜索树
二叉搜索树

当要进行查找时,会按小于往左搜索,大于往右搜索的规则去寻找。二叉搜索树只存了单个节点值,树的高度有可能会很高,如果用来存储索引数据,效率将会降低,不适用于 mysql 的索引,我们来看看 B 树吧:

B 树

一个节点可以存储多个数据值。当然,在插入删除时需要做对应的拆分或合并动作。

而且 B 树允许在非叶子节点也存储具体数据,这意味着在扫描搜索时也会将数据加载进来,这无疑增加了磁盘 IO。

对于磁盘 IO 要求高的 mysql 而言,B 树也很不划算,所以 B+ 树成了最好的选择,它长这样的:

B+ 树

B+ 树只在叶子节点存储具体的数据(注:数据可以是真正的行数据也可以是定位到行数据的指针地址),而非叶子节点值只存放索引数据,这样可以降低磁盘 IO,还能充分利用磁盘的预读功能,批量的加载索引数据。

hash 索引

hash 索引

hash 索引将列通过 hash 运算得到 hash code,然后将 hash code 跟数据行的指针地址关联在一起,下次查找时只需查找对应 hash code 的数据行地址即可。

hash 索引非常的紧凑,查找速度很快,适用于内存存储引擎的应用。不过它只能精确查询,不支持范围查找,也不能直接进行排序。限制还是挺多的。

全文索引

全文索引主要是用于文档查找,像我们可能会从多篇文章中查找包含某些词语的文章,这时就可以使用全文索引了。虽然 like 也可以使用,但是效率太低了。

全文索引在接收到文档时,会对它进行分词处理,以获取到关键词。然后会将关键词和属于这个文档的 id 关联起来。

下次查找,就会先到关键词列表里找到关联的文档 id ,最后利用文档 id 去查找到文档数据。

总结

索引所涉及的知识点还是挺多的,从了解索引用好索引再到优化索引,我想这应该是我们进行查询优化的必经之路吧。希望本文能为大家带来不一样的认识,也欢迎一起探讨!

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
7天前
|
缓存 关系型数据库 MySQL
MySQL索引策略与查询性能调优实战
在实际应用中,需要根据具体的业务需求和查询模式,综合运用索引策略和查询性能调优方法,不断地测试和优化,以提高MySQL数据库的查询性能。
|
29天前
|
存储 关系型数据库 MySQL
阿里面试:为什么要索引?什么是MySQL索引?底层结构是什么?
尼恩是一位资深架构师,他在自己的读者交流群中分享了关于MySQL索引的重要知识点。索引是帮助MySQL高效获取数据的数据结构,主要作用包括显著提升查询速度、降低磁盘I/O次数、优化排序与分组操作以及提升复杂查询的性能。MySQL支持多种索引类型,如主键索引、唯一索引、普通索引、全文索引和空间数据索引。索引的底层数据结构主要是B+树,它能够有效支持范围查询和顺序遍历,同时保持高效的插入、删除和查找性能。尼恩还强调了索引的优缺点,并提供了多个面试题及其解答,帮助读者在面试中脱颖而出。相关资料可在公众号【技术自由圈】获取。
|
1月前
|
存储 NoSQL 关系型数据库
为什么MySQL不使用红黑树做索引
本文详细探讨了MySQL索引机制,解释了为何添加索引能提升查询效率。索引如同数据库的“目录”,在数据量庞大时提高查询速度。文中介绍了常见索引数据结构:哈希表、有序数组和搜索树(包括二叉树、平衡二叉树、红黑树、B-树和B+树)。重点分析了B+树在MyISAM和InnoDB引擎中的应用,并讨论了聚簇索引、非聚簇索引、联合索引及最左前缀原则。最后,还介绍了LSM-Tree在高频写入场景下的优势。通过对比多种数据结构,帮助理解不同场景下的索引选择。
78 6
|
1月前
|
SQL 关系型数据库 MySQL
案例剖析:MySQL唯一索引并发插入导致死锁!
案例剖析:MySQL唯一索引并发插入导致死锁!
106 0
案例剖析:MySQL唯一索引并发插入导致死锁!
|
1月前
|
存储 关系型数据库 MySQL
Mysql(4)—数据库索引
数据库索引是用于提高数据检索效率的数据结构,类似于书籍中的索引。它允许用户快速找到数据,而无需扫描整个表。MySQL中的索引可以显著提升查询速度,使数据库操作更加高效。索引的发展经历了从无索引、简单索引到B-树、哈希索引、位图索引、全文索引等多个阶段。
63 3
Mysql(4)—数据库索引
|
20天前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第27天】本文深入探讨了MySQL的索引策略和查询性能调优技巧。通过介绍B-Tree索引、哈希索引和全文索引等不同类型,以及如何创建和维护索引,结合实战案例分析查询执行计划,帮助读者掌握提升查询性能的方法。定期优化索引和调整查询语句是提高数据库性能的关键。
97 1
|
1月前
|
存储 关系型数据库 MySQL
如何在MySQL中进行索引的创建和管理?
【10月更文挑战第16天】如何在MySQL中进行索引的创建和管理?
63 1
|
21天前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第26天】数据库作为现代应用系统的核心组件,其性能优化至关重要。本文主要探讨MySQL的索引策略与查询性能调优。通过合理创建索引(如B-Tree、复合索引)和优化查询语句(如使用EXPLAIN、优化分页查询),可以显著提升数据库的响应速度和稳定性。实践中还需定期审查慢查询日志,持续优化性能。
49 0
|
1月前
|
监控 关系型数据库 MySQL
MySQL数据表索引命名规范
MySQL数据表索引命名规范
60 1
|
1月前
|
存储 SQL 关系型数据库
mysql中主键索引和联合索引的原理与区别
本文详细介绍了MySQL中的主键索引和联合索引原理及其区别。主键索引按主键值排序,叶节点仅存储数据区,而索引页则存储索引和指向数据域的指针。联合索引由多个字段组成,遵循最左前缀原则,可提高查询效率。文章还探讨了索引扫描原理、索引失效情况及设计原则,并对比了InnoDB与MyISAM存储引擎中聚簇索引和非聚簇索引的特点。对于优化MySQL性能具有参考价值。
下一篇
无影云桌面