MySQL索引优化

article/2025/11/7 6:54:24

MySQL索引优化

  • 一、优化索引的方法
  • 二、优化步骤
    • 前缀索引优化
    • 覆盖索引优化
    • 主键索引最好是自增的
    • 索引最好设置为NOT NULL
    • 防止索引失效
  • 总结

一、优化索引的方法

这里说一下几种常见优化索引的方法:

前缀索引优化;
覆盖索引优化;
主键索引最好是自增的;
防止索引失效

二、优化步骤

前缀索引优化

前缀索引顾名思义就是使用某个字段中字符串的前几个字符建立索引,那我们为什么需要使用前缀来建立索引呢?

使用前缀索引是为了减小索引字段大小,可以增加一个索引页中存储的索引值,有效提高索引的查询速度。在一些大字符串的字段作为索引时,使用前缀索引可以帮助我们减小索引项的大小。

不过,前缀索引有一定的局限性,例如:

order by 就无法使用前缀索引;
无法把前缀索引用作覆盖索引;

覆盖索引优化

覆盖索引是指 SQL 中 query 的所有字段,在索引 B+Tree 的叶子节点上都能找得到的那些索引,从二级索引中查询得到记录,而不需要通过聚簇索引查询获得,可以避免回表的操作。

假设我们只需要查询商品的名称、价格,有什么方式可以避免回表呢?

我们可以建立一个联合索引,即「商品ID、名称、价格」作为一个联合索引。如果索引中存在这些数据,查询将不会再次检索主键索引,从而避免回表。

所以,使用覆盖索引的好处就是,不需要查询出包含整行记录的所有信息,也就减少了大量的 I/O 操作。

主键索引最好是自增的

我们在建表的时候,都会默认将主键索引设置为自增的,具体为什么要这样做呢?又什么好处?

InnoDB 创建主键索引默认为聚簇索引,数据被存放在了 B+Tree 的叶子节点上。也就是说,同一个叶子节点内的各个数据是按主键顺序存放的,因此,每当有一条新的数据插入时,数据库会根据主键将其插入到对应的叶子节点中。

如果我们使用自增主键,那么每次插入的新数据就会按顺序添加到当前索引节点的位置,不需要移动已有的数据,当页面写满,就会自动开辟一个新页面。因为每次插入一条新记录,都是追加操作,不需要重新移动数据,因此这种插入数据的方法效率非常高。

如果我们使用非自增主键,由于每次插入主键的索引值都是随机的,因此每次插入新的数据时,就可能会插入到现有数据页中间的某个位置,这将不得不移动其它数据来满足新数据的插入,甚至需要从一个页面复制数据到另外一个页面,我们通常将这种情况称为页分裂。页分裂还有可能会造成大量的内存碎片,导致索引结构不紧凑,从而影响查询效率

举个例子,假设某个数据页中的数据是1、3、5、9,且数据页满了,现在准备插入一个数据7,则需要把数据页分割为两个数据页:

在这里插入图片描述
出现页分裂时,需要将一个页的记录移动到另外一个页,性能会受到影响,同时页空间的利用率下降,造成存储空间的浪费。

而如果记录是顺序插入的,例如插入数据11,则只需开辟新的数据页,也就不会发生页分裂:
在这里插入图片描述
因此,在使用 InnoDB 存储引擎时,如果没有特别的业务需求,建议使用自增字段作为主键。

另外,主键字段的长度不要太大,因为主键字段长度越小,意味着二级索引的叶子节点越小(二级索引的叶子节点存放的数据是主键值),这样二级索引占用的空间也就越小

索引最好设置为NOT NULL

为了更好的利用索引,索引列要设置为 NOT NULL 约束。有两个原因:

第一原因:索引列存在 NULL 就会导致优化器在做索引选择的时候更加复杂,更加难以优化,因为可为 NULL 的列会使索引、索引统计和值比较都更复杂,比如进行索引统计时,count 会省略值为NULL 的行。

第二个原因:NULL 值是一个没意义的值,但是它会占用物理空间,所以会带来的存储空间的问题,会导致更多的存储空间占用,因为 InnoDB 默认行存储格式COMPACT,会用 1 字节空间存储 NULL 值列表,如下图的黄色部分:
在这里插入图片描述

防止索引失效

用上了索引并不意味着查询的时候会使用到索引,所以我们心里要清楚有哪些情况会导致索引失效,从而避免写出索引失效的查询语句,否则这样的查询效率是很低的。

发生索引失效的情况:

当我们使用左或者左右模糊匹配的时候,也就是 like %xx 或者 like %xx%这两种方式都会造成索引失效;

当我们在查询条件中对索引列做了计算、函数、类型转换操作,这些情况下都会造成索引失效;

联合索引要能正确使用需要遵循最左匹配原则,也就是按照最左优先的方式进行索引的匹配,否则就会导致索引失效。

在 WHERE 子句中,如果在 OR 前的条件列是索引列,而在 OR 后的条件列不是索引列,那么索引会失效。

我上面说的是常见的索引失效场景,实际过程中,可能会出现其他的索引失效场景,这时我们就需要查看执行计划,通过执行计划显示的数据判断查询语句是否使用了索引。

对于执行计划,参数有:

possible_keys 字段表示可能用到的索引;

key 字段表示实际用的索引,如果这一项为 NULL,说明没有使用索引;

key_len 表示索引的长度;

rows 表示扫描的数据行数。

type 表示数据扫描类型,我们需要重点看这个。

type 字段就是描述了找到所需数据时使用的扫描方式是什么,常见扫描类型的执行效率从低到高的顺序为

ALL(全表扫描);

index(全索引扫描);

range(索引范围扫描);

ref(非唯一索引扫描);

eq_ref(唯一索引扫描);

const(结果只有一条的主键或唯一索引扫描)。

考虑到查询效率问题,要尽量避免全表扫描和全索引扫描,也要避免 extra 的结果为 using filesort 的语句。

总结

这次主要介绍了索引的原理、分类和使用。我把重点总结在了下面这个表格
在这里插入图片描述


http://chatgpt.dhexx.cn/article/hECucAgj.shtml

相关文章

Android底层到上层的开发流程

安卓系统整体框架图如下: 简单总结如下: 1、在kernel层编写你的驱动程序:生成设备文件节点跟上一层传输数据,主要调用函数copy_to_user和copy_from_user,注意赋节点权限问题。 2、在HAL层封装对上提供的函数接口&…

【Android】Android底层开发实战

本书分为四个部分:第一部分为预备知识篇,简要介绍嵌入式系统的定义与软硬件开发以及Android开发环境的搭建。第二部分为系统结构篇,主要介绍Android系统的源码结构、内核与相关工具以及环境库。第三部分为驱动设计篇,主要介绍Andr…

我做了几年的Android应用层开发,为什么还要去学习安卓系统知识?

作为一个工作了好几年的Android应用层开发者,我准备在工作之余干一件事情,那就是学习Android系统知识,为什么要做这个决定呢? 其主要原因是想在Android应用层开发进阶 这个说起来并非易事,可能在很多人的认知里&…

一个Android应用层开发如何转型深入Android Framework?

作为一个工作了好几年的Android应用层开发者,准备在工作之余干一件事情,那就是分享一些Android系统知识,为什么决定要做这个呢,理由如下: 帮助更多人转型Android系统开发 不知何时起,单纯的Android应用层…

android底层开发-android基础架构

android architecture 在安卓中,最经典的架构就是分四层,分别是application、framework、libraries、kernel四层,通过这四层将android的整个架构都丰满起来 其架构图如下 android 系统组成 Process FW: android 系统固件&#…

Android Framework 开发揭解密,移动开发者必须掌握的底层原理

作为过来人,发现很多学习者和实践者都在 Android Framework上面临着很多的困扰,比如: 工作场景中遇到难题,往往只能靠盲猜和感觉,用临时性的补救措施去掩盖,看似解决了问题,但下次同样的问题又会…

Android系统底层架构【译】

Android系统底层架构 转载请注明来源:http://blog.csdn.net/lifeshow 设备移植 Android提供了设备移植和支持方面有较大的自由度,可以制定自有的设备规范和驱动。通过硬件抽象层(HAL-Hardware Abstraction Layer),可以…

嵌入式Android底层开发

嵌入式Linux主要有这几部分&#xff1a; Bootloader&#xff1a;主要用于引导Linux内核到内存中&#xff0c;让内核进行自解压并运行 zImage&#xff1a;带自解压的Linux内核 <Board>.dtb&#xff1a;每个型号的主板都有对应的设备树(保存对应的设备型号等信息&#x…

android 底层系统开发,Android底层

概述-Android系统架构 Android系统架构 概述-Application Application Android平台不仅仅是操作系统&#xff0c;同时也包含了许多应用&#xff0c;如桌面&#xff0c;浏览器&#xff0c;视频客户端&#xff0c;摄像头等。用JAVA编写&#xff0c;可以被开发人员开发的其他应用程…

Android 开发之 ---- 底层驱动开发(二)

Android 设备驱动&#xff08;下&#xff09; MTD 驱动 Flash 驱动通常使用 MTD &#xff08;memory technology device )&#xff0c;内存技术设备。 MTD 的字符设备&#xff1a; /dev/mtdX 主设备号 90. MTD 的块设备&#xff1a; /dev/block/mtdblockX 主设备号 13. MTD 驱…

写给Android App开发人员看的Android底层知识(1)

这个系列的文章一共8篇&#xff0c;我酝酿了很多年&#xff0c;参考了很多资源&#xff0c;查看了很多源码&#xff0c;直到今天把它写出来&#xff0c;也是战战兢兢&#xff0c;生怕什么地方写错了&#xff0c;贻笑大方。 &#xff08;一&#xff09;引言 早在我还是Android菜…

读懂底层,才是安卓真正开始的时候

对于android开发&#xff0c;我们大部分工作都是在应用层&#xff0c;但为了体现"技术含量"&#xff0c;以及"知其所以然"&#xff0c;以便在遇到具体问题时不至于束手无策&#xff0c;因此有必要了解底层的工作机制。 比如Android NDK 开发可能在平时的项…

Android 开发之 ---- 底层驱动开发

说到 android 驱动是离不开Linux驱动的。Android内核采用的是Linux2.6内核&#xff08;最近Linux 3.3已经包含了一些Android代码&#xff09;。但Android并没有完全照搬Linux系统内核&#xff0c;除了对Linux进行部分修正&#xff0c;还增加了不少内容。android 驱动主要分两种…

Android 开发之 ---- 底层驱动开发(一)

驱动概述 说到 android 驱动是离不开 Linux 驱动的。Android 内核采用的是 Linux2.6 内核 &#xff08;最近Linux 3.3 已经包含了一些 Android 代码&#xff09;。但 Android 并没有完全照搬 Linux 系统内核&#xff0c;除了对Linux 进行部分修正&#xff0c;还增加了不少内容。…

Android底层开发

学习书籍&#xff1a;Android底层开发实践 使用代码&#xff1a;AOSP源码 带的行表示关键点&#xff1b; 橙色背景的文字表示&#xff1a;整编log分析的关键字 绿色“待补充”文字表示&#xff1a;有待补充内容 -----第三章 Android系统开发环境搭建 3.1 Android上的开…

ELK日志分析系统(二)之ELK搭建部署

文章目录 引言一、Elasticsearch 集群部署&#xff08;在Node1上操作&#xff09;1、准备环境2、部署安装Elasticsearch软件3、配置Elasticsearch主配置文件4、创建数据存放路径并授权5、查看node1节点信息 二、Elasticsearch 集群部署&#xff08;在Node2上操作&#xff09;1、…

ELK日志分析系统之ELK搭建部署

文章目录 配置ELK日志分析系统1.配置elasticsearch环境2.部署elasticsearch软件2.1 安装Elasticsearch软件2.2 加载系统服务2.3 修改elasticsearch主配置文件2.4 创建数据存放文件路径并授权2.5 启动elasticsearch2.6 查看node1节点信息2.7 查看集群状态信息Elasticsearch 集群…

运维必备——ELK日志分析系统

目录 一、ELK日志分析系统概述&#xff08;1&#xff09;传统日志服务器的优点与缺点和为什么要使用ELK日志分析系统&#xff08;2&#xff09;ELK日志分析系统日志的分类&#xff08;3&#xff09;ELK日志分析系统的分类——Elasticsearch&#xff1a;——Logstash&#xff1a…

ELK 日志分析系统

目录 引言一、ELK 日志分析系统简介1. 日志服务器2. ELK 是什么3. Logstash 四种工具4. 日志处理步骤 二、Elasticsearch 的基础核心概念1. 概述2. 关系型数据库与 Elasticsearch 对应的关系3. 核心概念 三、Logstash 介绍1. logStash 的主要组件2. LogStash 主机分类 四、Kiba…

ELk日志分析系统搭建

一、什么是ELK ​ ELK是Elasticsearch Logstash Kibana 这种架构的简写. 二、ELK常见的架构 Elasticsearch Logstash Kibana 这是一种最简单的架构。这种架构&#xff0c;通过logstash收集日志&#xff0c;Elasticsearch分析日志&#xff0c;然后在Kibana(web界面)中展示。…