MySQL强化关键_019_索引优化

article/2025/6/9 11:06:20

目  录

一、最左前缀原则

1.完全使用索引 

2.部分使用索引

3.不使用索引

4.效率折损

(1)使用范围查找

(2)索引断开

 二、索引失效场景

1. 索引列参与运算

2.索引列模糊查询以“%”开始

3.索引列是字符串类型,查询省略单引号

4.查询条件包含“or”,其中有未添加索引的字段 

5.查询符合条件的记录在表中占比较大

三、指定索引

 四、覆盖索引

1.说明

2.实例

五、前缀索引

六、单列索引与复合索引的选择

七、创建索引的原则


一、最左前缀原则

# 初始化
drop table if exists t_customer;
create table t_customer(id int primary key auto_increment,name varchar(10),age int,gender char(2),email varchar(20)
);
insert into t_customer(name, age, gender, email) values('刘林', 21, '女', '2238953721@999.com'),('王刚', 23, '男', '1477123899@999.com'),('赵辉', 19, '男', '3287654466@999.com'),('何钰', 20, '女', '7981112520@999.com'),('周洋', 27, '男', '6287553412@999.com');create index index_tcustomer_nag on t_customer(name, age, gender);show index from t_customer;

         若要索引生效,必须遵循最左前缀原则。即上述为 t_customer 创建了name,age,gender 联合索引,添加顺序如此。则在进行查询时,如果 where 条件中没有 name 字段参与,则复合索引失效。

        条件中必须要有最左侧字段参与,这样复合索引才会生效。最具有唯一性的字段应该放在最左侧。


1.完全使用索引 

explain select * from t_customer where name = '何钰' and age = 20 and gender = '女';


2.部分使用索引

explain select * from t_customer where name = '何钰' and age = 20;explain select * from t_customer where name = '何钰';explain select * from t_customer where name = '何钰' and gender = '女';


3.不使用索引

explain select * from t_customer where age = 20 and gender = '女';


4.效率折损

(1)使用范围查找

        使用了范围查找,若范围条件不添加等号,则范围条件右侧列不会使用索引。

        如下实例,从【key_len】字段可以看出:第一条【gender】字段没有使用索引。而第二条完全使用了索引。

explain select * from t_customer where name = '何钰' and age > 20 and gender = '女';explain select * from t_customer where name = '何钰' and age >= 20 and gender = '女';


(2)索引断开

        条件中使用了索引最左侧字段,但是没有使用索引中的全部字段且间断使用,会使间断的字段不使用索引。

        如下方第一条,条件中没有使用【age】字段,而导致间断,所以【gender】字段没有使用索引。而第二条完全使用了索引。


 二、索引失效场景

# 初始化
drop table if exists t_emp;
create table t_emp(id int primary key auto_increment,name varchar(10),sal int,age char(2)
);
insert into t_emp(name, sal, age) values('刘强', 6000, 37),('川建国', 2000, 53),('郭珊珊', 9000, 27);create index index_temp_name on t_emp(name);
create index index_temp_sal on t_emp(sal);
create index index_temp_age on t_emp(age);show index from t_emp;


1. 索引列参与运算

explain select * from t_emp where sal * 10 > 50000;


2.索引列模糊查询以“%”开始

explain select * from t_emp where name like '%珊珊';


3.索引列是字符串类型,查询省略单引号

explain select * from t_mep where name = 郭珊珊;


4.查询条件包含“or”,其中有未添加索引的字段 

-- 查看执行计划
explain select * from t_emp where age = '53' or sal = 2000;-- 删除sal索引
alter table t_emp drop index index_temp_sal;-- 查看执行计划
explain select * from t_emp where age = '53' or sal = 2000;


5.查询符合条件的记录在表中占比较大

# 新插入几条数据
insert into t_emp(name, sal, age) values('王琳', 1800, 20),('张昂', 3000, 23),('李冬雪', 4000, 33),('王子安', 6500, 47),('陆佳佳', 7000, 28),('王明', 1000, 26),('邱钰红', 2500, 31),('黄灿灿', 10000, 38);# 创建sal索引
create index index_temp_sal on t_emp(sal);# 查询计划
explain select * from t_emp where sal > 1500;explain select * from t_emp where sal > 8000;

# 执行计划
explain select * from t_emp where age is null;# 将age字段全部更新为null
update t_emp set age = null;# 执行计划
explain select * from t_emp where age is null;

# 执行计划
explain select * from t_emp where age is not null;# 将age字段全部更新为not null
update t_emp set age = 23;# 执行计划
explain select * from t_emp where age is not null;


三、指定索引

  1. 当一个字段上既有单列索引,也有复合索引,可以通过下述 SQL 语句指定索引:
    1. use index(索引名):建议使用该索引。MySQL 会根据实际效率考虑是否使用;
    2. ignore index(索引名):忽略该索引;
    3. force index(索引名):强制使用该索引。
# 查看索引
show index from t_emp;# 为 t_emp 添加一个复合索引
create index index_temp_nsa on t_emp(name, sal, age);# 查看索引
show index from t_emp;# 执行计划
explain select * from t_emp where name = '郭珊珊';
explain select * from t_emp use index(index_temp_nsa) where name = '郭珊珊';
explain select * from t_emp ignore index(index_temp_name) where name = '郭珊珊';
explain select * from t_emp force index(index_temp_nsa) where name = '郭珊珊';


 四、覆盖索引

1.说明

        select 后的字段,尽可能是索引所覆盖的字段,如此可以避免“回表”。

        尽量避免使用【select * 】,因为其容易导致“回表”操作。


2.实例

        t_user 表字段有: id,name,password,realname,birth,email。表中数据有600万条,请针对下述 SQL 给出优化方案。

select id, name, realname from t_user where name = '郭珊珊';

         建议给 name 和 realname 两个字段添加联合索引,减少回表操作,大大提升效率。


五、前缀索引

        若一个字段类型是 varchar 或 text,直接对其创建索引会使索引体积较大。

        那么,可以将字符串前几个字符截取下来当作索引,这种索引被称为前缀索引。

# 为t_emp表的name字段前两个字符创建索引
create index index_temp_subname on t_emp(name(2));# 截取字符数计算公式,其值越接近于1,越具有唯一性
select count(distinct substring(字段名, 1, 前几个字符)) / count(*) from 表名;select count(distinct substring(name, 1, 2)) / count(*) from t_emp;

六、单列索引与复合索引的选择

        当查询语句有多个条件,建议将这些列创建为复合索引,因为创建单列索引容易造成“回表”操作。


七、创建索引的原则

  1. 表中数据量庞大,通常超过百万;
  2. 经常出现在 where、order by、group by 后边的字段建议添加索引;
  3. 创建索引的字段具有较强的唯一性;
  4. 字段存储文本,内容较大,一定要创建前缀索引;
  5. 尽量使用复合索引,避免回表查询;
  6. 若一个字段中的数据不会为 null,建议建表时添加 not null 约束。如此优化器知道使用哪个索引列更有效;
  7. 不要创建太多的索引,因为对数据进行增删改时,索引需要重新排序;
  8. 如果较少查询,频繁增删改,不建议添加索引。

http://www.hkcw.cn/article/DHMarxdHqF.shtml

相关文章

ABAP锁对象

1、锁表 在一些业务场景中,我们需要将某张表或某张表中的某些数据锁定,防止多人对该表进行操作,导致数据出现问题。SAP对于表的锁定,有专门的锁对象。 1.1、创建锁 事务代码SE11,表的锁对象名称,需要以E…

YOLO-V2 (学习记录)

目录 一、记录YOLO-v2 的处理流程步骤 二、优势与不足 三、细节分析 1.候选框K-means计算细节 2.网络输出 3.损失函数(Loss Function) 学习之前,需要补充下论文中提到知识点。 1.什么是Batch Normalization 参考博文:Batc…

AI Coding 资讯 2025-06-03

Prompt工程 RAG-MCP:突破大模型工具调用瓶颈,告别Prompt膨胀 大语言模型(LLM)在工具调用时面临Prompt膨胀和决策过载两大核心挑战。RAG-MCP创新性地引入检索增强生成技术,通过外部工具向量索引和动态检索机制,仅将最相关的工具信…

CAMEL-AI开源自动化任务执行助手OWL一键整合包下载

OWL 是由 CAMEL-AI 团队开发的开源多智能体协作框架,旨在通过动态智能体交互实现复杂任务的自动化处理,在 GAIA 基准测试中以 69.09 分位列开源框架榜首,被誉为“Manus 的开源平替”。我基于当前最新版本制作了免安装一键启动整合包。 CAMEL-…

线程池RejectedExecutionException异常

文章目录 1、报错2、定位3、修复4、线程池使用的一点思考 1、报错 检索项目日志时,发现一个异常堆栈信息,核心报错: java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.CompletableFuture$AsyncSupply480a10c7…

视频监控管理平台EasyCVR安防小知识:监控摄像头异响问题排查与处理

在视频监控系统广泛应用于日常生活的当下,监控摄像头出现异响是常见且影响使用体验的问题。为快速定位和解决该问题,特制定本应用解决方案,依据异响来源分为硬盘录像机异响与监控摄像头异响两类进行处理。 一、硬盘录像机发出异响 硬盘录像机…

NX890NX894美光固态闪存NX906NX908

美光NX系列固态闪存深度解析 技术架构与性能突破 美光NX系列固态闪存(如NX890、NX894、NX906、NX908)的技术核心基于G9 NAND技术,通过优化晶体管结构与制程工艺,显著提升存储密度与读写速度。例如,NX895的MT29F8T08G…

RHEL7安装教程

RHEL7安装教程 下载RHEL7镜像 通过网盘分享的文件:RHEL 7.zip 链接: https://pan.baidu.com/s/1ExLhdJigj-tcrHJxIca5XA?pwdjrrj 提取码: jrrj --来自百度网盘超级会员v6的分享安装 1.打开VMware,新建虚拟机,选择自定义然后下一步 2.点击…

无人机智能识别交通目标,AI视觉赋能城市交通治理新高度

在城市化快速发展的当下,如何实现对道路交通的智能化管理、保障出行安全,成为城市治理的重要命题。传统的交通监控往往依赖地面摄像头,受限于固定视角与安装环境。而今,随着人工智能与无人机技术的深度融合,一种更高效…

使用 HTML + JavaScript 实现文章逐句高亮朗读功能

在这个信息爆炸的时代,我们每天都要面对大量的文字阅读。无论是学习、工作还是个人成长,阅读都扮演着至关重要的角色。然而,在快节奏的生活中,我们往往难以找到足够的安静时间专注于阅读。本文用 HTML JavaScript 实现了一个基于…

《TCP/IP 详解 卷1:协议》第5章:Internet协议

IPv4和IPv6头部 IP是TCP/IP协议族中的核心协议。所有TCP、UDP、ICMP和IGMP 数据都通过IP数据报传输。IP提供了一种尽力而为、无连接的数据报交付服务。 IP头部字段 IPv4 头部通常为 20 字节(无选项时),而 IPv6 头部固定为 40 字节。IPv6 不…

WPS word 已有多级列表序号

wps的word中,原来已生成的文档里,已存在序号。比如,存在2、2.1、2.1.1、2.1.1.1、2.1.1.1.1 5层序号,而且已分为5级。但增加内容的时候,并不会自动增加序号,应该如何解决? 原来长这样&#xff…

5 个经典的大模型微调技术

传统微调方法(如下图所示)对于大语言模型而言并不可行,因为这些模型具有数百亿甚至千亿的参数量,而且显存需求高达数百GB,并非所有人都能获得如此规模的计算资源。 但如今,我们拥有多种优化大语言模型的微调…

爱耕云课时管理系统评测

1 核心功能模块与代码实现 1.1 智能排课引擎(Python伪代码示例) 爱耕云的排课系统采用约束满足算法(Constraint Satisfaction Problem)解决教培机构最头疼的资源冲突问题。该系统将教师、教室、课程和时间段抽象为多维资源&…

Go的隐式接口机制

正确使用Interface 不要照使用C/Java等OOP语言中接口的方式去使用interface。 Go的Interface的抽象不仅可以用于dynamic-dispatch 在工程上、它最大的作用是:隔离实现和抽象、实现完全的dependency inversion 以及interface segregation(SOLID principle中的I和D)。…

Linux总结

一、Linux linux系统的构成 1.linux系统内核:提供最核心的功能,如:调度CPU、调度内存、调度文件系统、调度网络通信、调度IO等。 2.系统级应用程序:出厂自带程序,可供用户快速上手操作系统。如:文件管理…

嵌入式复习小练

1.ARM处理器中用作程序计数器PC的通用寄存器是() A.R12 B.R13 C.R14 D.R15 答案:D。在 ARM 处理器中,R15 用作程序计数器(PC) ,用于存放下一条要执行指令的地址 2.以下关于ARM程序状态寄存器C…

Python Day41学习(日志Day8复习)

对信贷数据中的离散特征重新进行独热编码 重写代码时出现的问题: .tolist()是一个方法对象,调用时须加()。刚开始书写时漏掉了(),导致报错。 复习“日志Day8”的内容 今日有点事耽搁了,少复习了些内容,明日继续加油&…

入门AJAX——XMLHttpRequest(Post)

一、前言 在上篇文章中,我们已经介绍了 HMLHttpRequest 的GET 请求的基本用法,并基于我提供的接口练习了两个简单的例子。如果你还没有看过第一篇文章,强烈建议你在学习完上篇文章后再学习本篇文章: 🔗入门AJAX——XM…

网络交换机:构建高效、安全、灵活局域网的基石

在数字化时代,网络交换机作为局域网(LAN)的核心设备,承担着数据转发、通信优化和安全防护的关键任务。其通过独特的MAC地址学习、冲突域隔离、VLAN划分等技术,显著提升了网络性能,成为企业、学校、医院等场景不可或缺的基础设施。…