当前位置: 首页 > news >正文

MySQL数据库索引详解

一、引言

当数据库数据量从万级突破至百万、千万级,查询延迟、业务卡顿往往成为制约系统效率的核心瓶颈。而索引,正是 MySQL 中解决这一问题的 “性能加速器”,就像书籍的目录,能让数据库跳过全表扫描的冗余操作,快速定位目标数据。作为数据库优化的核心技术,索引的设计是否合理,直接决定了查询效率的高低,甚至影响整个系统的稳定性。但多数开发者常陷入 “滥用索引” 或 “索引失效” 的误区,反而拖慢性能。本文将介绍不同种类的索引,让 MySQL 查询效率实现质的飞跃。

二、InnoDB 的索引

2.1 主键索引

  • 主键索引的叶子节点存的是整行数据。在 InnoDB 里,主键索引也被称为聚簇索引(clustered index)。
  •  非主键索引的叶子节点内容是主键的值。在 InnoDB 里,非主键索引也被称为二级索引(secondary index)。

面试的时候经典问题又来了:

  • select * from Table where id = 00001,即主键查询方式
  • select * from Table where year = 2012,即普通索引查询方式

这两条查询语句在性能上有什么不同?我们通过上图可以知道,基于主键查询,只需要检索 ID 这棵 B+树,就可以直接得到结果数据;而普通索引查询,需要先搜索 year 这棵 B+树,得到 ID 的值为 00001,再到 ID 索引树搜索一次,这个过程也被称为回表。也就是说,基于非主键索引的查询需要多扫描一次索引树。所以,我们在应用中应该尽量使用主键查询。

2.2 覆盖索引

我们说,尽量使用主键索引,而不是一般索引,是为了避免回表,减少一次 B+ 树的扫描。那么,是不是有另外一种可能的方式,就是只扫描一般索引树,不扫描主键索引树呢?这就是覆盖索引

如果执行的语句是 select ID, year from T able where year = 2012,这时只需要查 ID 的值,而 ID 的值已经在 year 索引树上了,因此可以直接提供查询结果,不需要回表。也就是说,在这个查询里面,索引 year 已经“覆盖了”我们的查询需求,我们称为覆盖索引。

覆盖索引,是一个非常常用的性能优化方式。但是,我们并不总是只返回 ID 就够了,我们可能还需要其他字段,比如 name。

这个时候,就出现了另外一个技术:联合索引。

2.3  联合索引

在我们的业务场景中,parkCode 是园区的唯一标识。也就是说,如果通过 parkCode 查询园区信息,只需要建立 parkCode 索引就可以了。这个时候建立(parkCode_name) 联合索引,是不是在浪费空间呢?

这个时候还是要分析具体业务,看查询园区名是不是高频请求,如果需要根据parkCode 查询园区名称,那么这个索引就非常必要,因为可以用到覆盖索引,不需要回表就可以获得查询结果。但是如果查询园区名称并不高频,或者说更多的时候需要和其他字段一起查询,那么就没有必要建立联合索引。

因为索引字段的维护是要付出代价的:

  • 时间代价:因为联合索引意味着索引的值会变得更细更多,那么每增加一条数据进行的索引调整就会更加频繁

  • 空间代价:因为每一个数据块的大小是固定的,每一条索引占用的空间越大,每个数据块可容纳的索引条数就更小,B+ 树的高度就会变大,进一步降低查询效率

2.4 最左前缀原则

B+树的索引,遵循最左前缀原则。也就是说,并不需要匹配索引的全部关键字信息,只要满足最左前缀,就可以利用索引来加速检索。这个最左前缀可以是联合索引的最左N个字段,也可以是字符串索引的最左M个字符。这个“最左”包含了两层意思:

  • 字符串索引的最左侧 M 个字符:比如使用  where name like ' 南%'就可以在字符串中进行匹配,而'%京'就无法进行匹配。

  • 联合索引的最左 N 个字段:比如对一个(area,name,year) 索引,如果查询条件是where area = '中区' and name = '武汉江夏' 就可以匹配到 area 与 name;而如果查询条件是 where area = '中区' and year = '2014',由于跳过了 name,就无法匹配 year,只能匹配到 area。

    • 这里面又引申出来一个原则,要充分发挥索引的复用能力,如果建立了(area,name,year) 联合索引,就没有必要单独建立(area)索引了,因为前一个联合索引可以兼容后面的独立索引。

    • 但是要注意,(a,b)索引可以覆盖(a) 索引,但是不能覆盖(b)索引,如果有比较高频的 b 的筛选条件,就需要建立(a,b)(b) 两个索引。

再次强调,索引是要付出代价的,所以:

  • 索引不是越多越好

  • 联合索引不是字段越多越好

2.5 给字符串加索引

不知道大家在创建索引的时候,有没有注意到后面这个字段,就是前缀长度。比如我们对用户的 email 创建索引,一种方式是

http://www.dtcms.com/a/609929.html

相关文章:

  • 多通道ADC数模转换器电池管理系统解决方案
  • Java 基础高频38问
  • 煤矿煤质分类数据集3406张5类别
  • MR30分布式I/O模块服务换热站项目,守护万家温暖
  • 唐山市城市建设规划局网站网站首页index.html
  • 大模型架构和原理二
  • 11.14 脚本网页 青蛙过河
  • 【算法专题训练】30、二叉树的应用
  • 深入解析IP, ICMP, OSPF, BGP四大核心网络协议
  • RAG系统中的文本分块技术:从基础策略到智能分块的深度解析
  • Bootstrap 4 Flex布局详解
  • APP网站建设开发企业发展网站建设增城
  • 我做网站了 圆通北京网站建设首选优达
  • Lidar调试记录Ⅲ之Ubuntu22.04+ROS2环境中安装colcon
  • 闵行网站制作设计公司wordpress wp polls
  • IntelliJ IDEA初始化指南
  • Unity ScriptedImporter 教程:自定义资源导入器
  • C语言编译器苹果 | 适用于macOS的高效C语言编译环境介绍
  • python(57) : 离线环境升级依赖
  • C++网络开发---客户端网络传输 libcurl
  • 电商项目练习实操(二)
  • 不使用后端接口导出excel的三种方式
  • leetcode 394 字符串解码
  • 如何做充值网站seo模拟点击软件源码
  • 好看的旅游网站模板下载镇江百度推广公司
  • 智慧物业|物业管理|基于SprinBoot+vue的智慧物业管理系统(源码+数据库+文档)
  • Android thermal (7)_thermal core
  • 网站的维护费用售后服务网站建设
  • Databend SQL nom Parser 性能优化
  • wordpress的标签页网站seo竞争分析工具