MySQL强化关键_019_索引优化

news2025/6/5 17:50:33

目  录

一、最左前缀原则

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.coloradmin.cn/o/2398189.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关于list集合排序的常见方法

目录 1、list.sort() 2、Collections.sort() 3、Stream.sorted() 4、进阶排序技巧 4.1 空值安全处理 4.2 多字段组合排序 4.3. 逆序 5、性能优化建议 5.1 并行流加速 5.2 原地排序 6、最佳实践 7、注意事项 前言 Java中对于集合的排序操作,分别为list.s…

不动产登记区块链系统(Vue3 + Go + Gin + Hyperledger Fabric)

好久没有介绍过新项目的制作了,之前做的一直都是Fisco Bcos的项目,没有介绍过Hyperledger Fabric的项目,这次来给大家分享下。 系统概述 不动产登记与交易平台是一个基于Hyperledger Fabric的综合性管理系统,旨在实现不动产登记…

从 GPT 的发展看大模型的演进

这是一个技术爆炸的时代。一起来看看 GPT 诞生后,与BERT 的角逐。 BERT 和 GPT 是基于 Transformer 模型架构的两种不同类型的预训练语言模型。它们之间的角逐可以从 Transformer 的编码解码结构角度来分析。 BERT(Bidirectional Encoder Representatio…

【Qt】构建目录设置

问题 ProjectRoot/├── src/ # 源代码│ ├── project1│ └── project2├── build/ # 构建目录│ ├── build-PCIeDemoApp-Desktop_Qt_5_9_7_MSVC2015_64bit-Debug/│ └── build-PCIeDemoApp-Desktop_Qt_5_9_7_MSVC2015_64bit-Rele…

Web后端快速入门(Maven)

Maven是apche旗下的一个开源项目,是一款用于管理和构建java项目的工具。 开源项目:Welcome to The Apache Software Foundation. Maven的作用: 依赖管理(方便快捷的管理项目依赖的资源,避免版本冲突问题&#xff09…

机器学习算法:逻辑回归

1. 基础概念 定义: 逻辑回归(Logistic Regression)是一种用于解决二分类问题的监督学习算法,通过概率预测样本属于某一类别的可能性。 核心特点:输出是概率值(0~1),通过阈值&#…

AI健康小屋+微高压氧舱:科技如何重构我们的健康防线?

目前,随着科技和社会的不断发展,人们的生活水平和方式有了翻天覆地的变化。 从吃饱穿暖到吃好喝好再到健康生活,观念也在逐渐发生改变。 尤其是在21世纪,大家对健康越来越重视,这就不得不提AI健康小屋和氧舱。 一、A…

如何做接口测试?

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 01、通用的项目架构 02、什么是接口 接口:服务端程序对外提供的一种统一的访问方式,通常采用HTTP协议,通过不同的url&#xff…

【JMeter】性能测试知识和工具

目录 何为系统性能 何为性能测试 性能测试分类 性能测试指标 性能测试流程 性能测试工具:JMeter(主测web应用) jmeter文件目录 启动方式 基本元件:元件内有很多组件 jmeter参数化 jmeter关联 自动录制脚本 直连数据库…

SOC-ESP32S3部分:25-HTTP请求

飞书文档https://x509p6c8to.feishu.cn/wiki/KL4RwxUQdipzCSkpB2lcBd03nvK HTTP(Hyper Text Transfer Protocol) 超文本传输协议,是一种建立在 TCP 上的无状态连接,整个基本的工作流程是客户端发送一个 HTTP 请求,说明…

字符编码全解析:ASCII、GBK、Unicode、UTF-8与ANSI

UTF - 8(全球字符能被唯一标识)、GBK、Unicode、ANSI 区别与关联 qwen模型分词器文件 1. ASCII(基础铺垫,理解编码起源) 作用:最早期为处理英文文本设计,是字符编码的基础,后演变成其他编码兼容的一部分 。范围:共 128 个字符(0 - 127),包含英文大小写字母、数字…

MaxCompute开发UDF和UDTF案例

文章目录 一、Java开发UDF1、创建Maven项目2、创建UDF类3、打包上传资源4、创建函数MyUDF5、SQL验证 二、Java开发UDTF1、创建Maven项目2、创建UDTF类3、打包上传更新资源4、创建函数MyUDTF5、SQL验证 三、常见问题1、发布函数报错 一、Java开发UDF 1、创建Maven项目 创建Mav…

49套夏日小清新计划总结日系卡通ppt模板

绿色小清新PPT模版,日系小清新PPT模版,粉红色PPT模版,蓝色PPT模版,草青色PPT模版,日系卡通PPT模版 49套夏日小清新计划总结日系卡通ppt模板:夏日小清新日系卡通PPT模版https://pan.quark.cn/s/9e4270d390fa…

告别硬编码!用工厂模式优雅构建可扩展的 Spring Boot 应用 [特殊字符]

嗨,各位技术伙伴们!👋 在日常的软件开发中,我们经常面临需求变更的挑战。如何构建一个既能满足当前需求,又能轻松应对未来变化的系统呢?答案往往藏在那些经典的设计模式中。 今天,我们就来聊聊…

Express教程【006】:使用Express写接口

文章目录 8、使用Express写接口8.1 创建API路由模块8.2 编写GET接口8.3 编写POST接口 8、使用Express写接口 8.1 创建API路由模块 1️⃣新建routes/apiRouter.js路由模块: /*** 路由模块*/ // 1-导入express const express require(express); // 2-创建路由对象…

mongodb集群之分片集群

目录 1. 适用场景2. 集群搭建如何搭建搭建实例Linux搭建实例(待定)Windows搭建实例1.资源规划2. 配置conf文件3. 按顺序启动不同角色的mongodb实例4. 初始化config、shard集群信息5. 通过router进行分片配置 1. 适用场景 数据量大影响性能 数据量大概达到千万级或亿级的时候&…

Starrocks Full GC日志分析

GC日志样例: [2025-06-03T07:36:06.1770800] GC(227) Pause Full (G1 Evacuation Pause) [2025-06-03T07:36:06.1960800] GC(227) Phase 1: Mark live objects [2025-06-03T07:36:06.9480800] GC(227) Cleaned string and symbol table, strings: 47009 processed,…

飞算 JavaAI 赋能老项目重构:破旧立新的高效利器

许多企业的 Java 老项目面临着代码陈旧、架构落后、维护困难等问题。老项目重构势在必行,却又因庞大的代码量、复杂的业务逻辑让开发团队望而却步。 老项目重构困境重重 传统的 Java 老项目往往在长期的迭代和维护中积累了诸多问题。一方面,代码质量堪…

typescript的Interface和Type

类型别名和接口非常相似,在大多数情况下你可以在它们之间自由选择。 几乎所有的 interface 功能都可以在 type 中使用,关键区别在于不能重新开放类型以添加新的属性,而接口始终是可扩展的。 // window.ts.transpileModule(src, {}); 这是调…

java后端生成心电图-jfreechart

用jfreechart生成心电图 先上成功的图片 上代码 1.导入包 implementation org.jfree:jfreechart:1.5.4implementation org.jfree:jcommon:1.0.242.实现代码 对数据进行滤波 转换单位 package com.shinrun.infrastructure.util;import java.util.ArrayList; import java.ut…