SQL提示与索引终章
✨博客主页:小小恶斯法克的博客
🎈该系列文章专栏:重拾MySQL-进阶篇
📜 感谢大家的关注! ❤️ 可以关注黑马IT,进行学习

目录
🚀SQL提示
🚀覆盖索引
🚀前缀索引
🚀前缀长度
🚀单列索引与联合索引
🚀索引设计原则
🚀SQL提示
目前tb_user表的数据情况如下 :

索引情况如下 :

把上述的 idx_user_age, idx_email 这两个之前测试使用过的索引直接删除。
drop index idx_user_age on tb_user;
drop index idx_email on tb_user;

执行SQL : explain select * from tb_user where profession = '电气工程 ';

很明显查询走了联合索引
执行SQL,创建profession的单列索引: create index idx_user_pro on tb_user(profession);

创建完单列索引之后,我们再执行语句explain select * from tb_user where profession = '电气工程 ';看看走哪个索引

测试结果,我们可以看到,possible_keys中 idx_user_pro_age_sta,idx_user_pro 这两个 索引都可能用到,最终MySQL选择了idx_user_pro_age_sta索引。这是MySQL自动选择的结果。
那么,我们能不能在查询的时候,自己来指定使用哪个索引呢?
当然可以指定使用特定的索引进行查询。在大多数数据库管理系统中,您可以在查询中明确指定要使用的索引。这通常通过在查询语句中添加关键字来实现,具体取决于您使用的数据库系统。例如,在许多 SQL 数据库中,您可以使用类似于
USE INDEX或FORCE INDEX的语法来指定要使用的索引。如果您正在使用 NoSQL 数据库或其他类型的数据存储,通常也会有类似的机制来允许您指定使用的索引。
请注意,虽然可以手动指定索引,但应该谨慎使用。数据库系统通常会自动选择最佳的索引,手动指定索引可能会导致性能问题,除非您对数据模式和查询性能有深入了解。
借助SQL提示完成手动指定索引
SQL提示,是优化数据库的一个重要手段,简单来说,就是在SQL语句中加入一些人为的提示来达到优 化操作的目的。
use index :建议MySQL使用哪一个索引完成此次查询(仅仅是建议, mysql内部还会再次进
行评估)。
explain select * from tb_user use index (idx_user_pro) where profession = '电气工程';

ignore index : 忽略指定的索引。
explain select * from tb_user ignore index (idx_user_pro) where profession = '电气工程';

force index : 强制使用索引。
explain select * from tb_user force index (idx_user_pro) where profession = '电气工
程';

🚀覆盖索引
尽量使用覆盖索引,减少select *。 那么什么是覆盖索引呢?覆盖索引是指 查询使用了索引,并且需要返回的列,在该索引中已经全部能够找到 。
覆盖索引是一种特殊类型的索引,它包含了在查询中涉及的所有字段,从而使得数据库系统无需访问实际的数据行就能够满足查询需求。这种索引覆盖了查询所需的所有列,因此称为"覆盖索引"。
当数据库执行查询时,如果能够仅通过索引就能够获取到需要的数据,那么数据库引擎就不必再去实际的数据表中查找相应的行,这样可以大大提高查询性能。覆盖索引通常用于查询中只需要返回索引列的情况,而不需要返回整个数据行的场景。
使用覆盖索引有以下几个优点:
- 减少IO操作:由于不需要访问实际的数据行,因此可以减少IO操作,提高查询性能。
- 减少内存消耗:覆盖索引可以减少数据库系统需要维护的内存空间,因为不需要缓存完整的数据行。
- 降低磁盘占用:由于不需要存储完整的数据行,覆盖索引可以节省磁盘空间。
要创建覆盖索引,您需要确保索引包含了查询中涉及的所有字段。在设计数据库时,考虑到查询的需求并合理地创建覆盖索引可以显著改善查询性能。
接下来,我们来看一组SQL的执行计划,看看执行计划的差别,然后再来具体做一个解析
explain select id, profession from tb_user where profession = '化工 ' and age =
38 and status =' 5 ' ;
explain select id,profession,age, status from tb_user where profession = '化工 '
and age = 38 and status = '5 ' ;

explain select id,profession,age, status, name from tb_user where profession = '化工 ' and age = 38 and status = '5 ' ;

explain select * from tb_user where profession = '化工 ' and age = 38 and status = '5 ';

从上述的执行计划我们可以看到,这四条SQL语句的执行计划前面所有的指标都是一样的,看不出来差异。但是此时,我们主要关注的是后面的Extra,前面两条SQL的结果为 Using where; Using Index ; 而后面两条SQL的结果为 : null 或 Using index condition
| Extra | 含义 |
| Using where; Using Index | 查找使用了索引,但是需要的数据都在索引列中能找到,所以不需 要回表查询数据 |
| Using index condition | 查找使用了索引,但是需要回表查询数据 |
因为,在tb_user表中有一个联合索引 idx_user_pro_age_sta,该索引关联了三个字段 profession、age、status,而这个索引也是一个二级索引,所以叶子节点下面挂的是这一行的主键id。所以当我们查询返回的数据在id、profession、age、status 之中,则直接走二级索引直接返回数据了。如果超出这个范围,就需要拿到主键id,再去扫描聚集索引,再获取额外的数据了,这个过程就是回表。而我们如果一直使用select * 查询返回所有字段值,很容易就会造成回表查询(除非是根据主键查询,此时只会扫描聚集索引)。
为了更清楚的理解,什么是覆盖索引,什么是回表查询,看下面的这组SQL的执行过程。(以下内容和图片均来自黑马)
表结构及索引示意图 :
id是主键,是一个聚集索引。 name字段建立了普通索引,是一个二级索引(辅助索引)
执行SQL : select * from tb_user where id = 2;

根据id查询,直接走聚集索引查询,一次索引扫描,直接返回数据,性能高。
执行SQL: selet id,name from tb_user where name = 'Arm';

虽然是根据name字段查询,查询二级索引,但是由于查询返回在字段为id,name,在name的二级索引中,这两个值都是可以直接获取到的,因为覆盖索引,所以不需要回表查询,性能高。
执行SQL: selet id,name,gender from tb_user where name = 'Arm';

由于在name的二级索引中,不包含gender,所以,需要两次索引扫描,也就是需要回表查询,性能相对较差一点
思考:
一张表 , 有四个字段 (id, username, password, status), 由于数据量大 , 需要对以下SQL语句进行优化 , 该如何进行才是最优方案 :
select id,username,password from tb_user where username = 'itcast';
答 : 针对于 username, password建立联合索引 , sql为 : create index idx_user_name_pass on tb_user(username,password);
这样可以避免上述的SQL语句,在查询的过程中,出现回表查询。
答:针对这个查询语句,最优的优化方案是创建一个覆盖索引,以便在查询时能够仅通过索引就获取所需的数据,而无需访问实际的数据行。在这种情况下,您可以创建一个包含 (username, id, password) 字段的索引。
以下是针对该表的创建覆盖索引的SQL语句:
CREATE INDEX idx_username_covering ON tb_user (username, id, password);通过创建这样的覆盖索引,数据库系统在执行上述查询时,只需要访问索引而无需再去实际的数据行中查找相应的列,从而提高了查询性能。
🚀前缀索引
当字段类型为字符串( varchar, text, longtext等)时,有时候需要索引很长的字符串,这会让 索引变得很大,查询时,浪费大量的磁盘IO,影响查询效率。此时可以只将字符串的一部分前缀,建立索引,这样可以大大节约索引空间,从而提高索引效率。
create index idx_xxxx on table_name (column (n)) ;
示例
为tb_user表的email字段,建立长度为5的前缀索引
create index idx_email_5 on tb_user (email (5));

🚀前缀长度
可以根据索引的选择性来决定,而选择性是指不重复的索引值(基数)和数据表的记录总数的比值,索引选择性越高则查询效率越高,唯一索引的选择性是1,这是最好的索引选择性,性能也是最好的。
前缀索引的查询流程

🚀单列索引与联合索引
单列索引:即一个索引只包含单个列。
联合索引:即一个索引包含了多个列。
我们先来看看 tb_user 表中目前的索引情况 :

在查询出来的索引中,既有单列索引,又有联合索引
我们来执行一条SQL语句,看看其执行计划:
explain select id,phone,name from tb_user where phone = '15377777775' and name = 'f';

通过上述执行计划我们可以看出来,在and连接的两个字段 phone、 name上都是有单列索引的,但是 最终mysql只会选择一个索引,也就是说,只能走一个字段的索引,此时是会回表查询的。
紧接着,我们再来创建一个phone和name字段的联合索引来查询一下执行计划
create unique index idx_user_phone_name on tb_user (phone,name);


此时,查询时,就走了联合索引,而在联合索引中包含 phone、 name的信息,在叶子节点下挂的是对应的主键id,所以查询是无需回表查询的。
在业务场景中,如果存在多个查询条件,考虑针对于查询字段建立索引时,建议建立联合索引,
而非单列索引。
如果查询使用的是联合索引,具体的结构示意图如下:

🚀索引设计原则
针对于数据量较大,且查询比较频繁的表建立索引。
针对于常作为查询条件(where)、排序( order by)、分组(group by)操作的字段建立索 引。尽量选择区分度高的列作为索引,尽量建立唯一索引,区分度越高,使用索引的效率越高。
如果是字符串类型的字段,字段的长度较长,可以针对于字段的特点,建立前缀索引。
尽量使用联合索引,减少单列索引,查询时,联合索引很多时候可以覆盖索引,节省存储空间, 避免回表,提高查询效率。
要控制索引的数量,索引并不是多多益善,索引越多,维护索引结构的代价也就越大,会影响增 删改的效率。
如果索引列不能存储NULL值,请在创建表时使用NOT NULL约束它。当优化器知道每列是否包含 NULL值时,它可以更好地确定哪个索引最有效地用于查询。
希望对大家有帮助!
相关文章:
SQL提示与索引终章
✨博客主页:小小恶斯法克的博客 🎈该系列文章专栏:重拾MySQL-进阶篇 📜 感谢大家的关注! ❤️ 可以关注黑马IT,进行学习 目录 🚀SQL提示 🚀覆盖索引 🚀前缀索引 &…...
基于OpenSSL的SSL/TLS加密套件全解析
概述 SSL/TLS握手时,客户端与服务端协商加密套件是很重要的一个步骤,协商出加密套件后才能继续完成后续的握手和加密通信。而现在SSL/TLS协议通信的实现,基本都是通过OpenSSL开源库,本文章就主要介绍下加密套件的含义以及如何在O…...
01-echarts如何绘制三维折线图
echarts如何绘制三维折线图 一、相关依赖包1、下载依赖2、引入依赖 二、创建图表盒子1、创建盒子2、定义数据3、编写方法1、初始化盒子2、设置配置项3、修改数据格式4、设置颜色数组4、设置name数组5、设置线三维和点三维6、添加配置项7、设置图表自适应 4、调用方法 三、整体代…...
Linux-共享内存
文章目录 前言一、system V共享内存申请共享内存挂载共享内存删除共享内存挂载删除共享内存 二、示例代码三.运行效果 前言 在这之前我们已经学习了两种进程间通信方式:匿名管道和命名管道。 从我们之前的学习已经知道,想让多个进程间进行通信就需要让他…...
深入分析 Linux 网络丢包问题
热门IT课程【视频教程】-华为/思科/红帽/oraclehttps://xmws-it.blog.csdn.net/article/details/134398330 所谓丢包,是指在网络数据的收发过程中,由于种种原因,数据包还没传输到应用程序中,就被丢弃了。这些被丢弃包的数量&#…...
web安全学习笔记【08】——算法1
思维导图在最后 #知识点: 1、Web常规-系统&中间件&数据库&源码等 2、Web其他-前后端&软件&Docker&分配站等 3、Web拓展-CDN&WAF&OSS&反向&负载均衡等 ----------------------------------- 1、APP架构-封装&原生态&…...
2024最新版Python 3.12.1安装使用指南
2024最新版Python 3.12.1安装使用指南 Installation and Configuration Guide to the latest version Python 3.12.1 in 2024 By Jackson Python编程语言,已经成为全球最受欢迎的编程语言之一;它简单易学易用,以标准库和功能强大且广泛外挂…...
Oracle 经典练习题 50 题
文章目录 一 CreateTable二 练习题1 查询"01"课程比"02"课程成绩高的学生的信息及课程分数2 查询"01"课程比"02"课程成绩低的学生的信息及课程分数3 查询平均成绩大于等于60分的同学的学生编号和学生姓名和平均成绩4 查询平均成绩小于…...
PyTorch的衍生资源
PyTorch作为深度学习领域的一个重要框架,自2016年首次发布以来经历了显著的发展。以下是PyTorch发展过程中的几个关键里程碑事件: 2016年: PyTorch于2016年首次发布,作为一个基于动态计算图的开源机器学习库,它提供了自…...
开源项目Git Commit规范与ChangeLog
一,conventional commit(约定式提交) Conventional Commits 是一种用于给提交信息增加人机可读含义的规范。它提供了一组用于创建清晰的提交历史的简单规则。 1.1 作用 自动化生成 CHANGELOG基于提交类型,自动决定语义化的版本变更向项目相关合作开发…...
【原理图PCB专题】OrCAD Capture CIS关闭开始界面
17.4版本 在打开OrCAD Capture CIS时会发现打开Start Page页面,那么如何将他关闭再也不看这个界面呢? 在窗口中输入SetOptionBool EnableStartPage 0 回车 重启软件后就再也不会弹出Start Page页面 如果没有发现Command Window那么将菜单栏view->C…...
【Linux】Ubuntu的gnome切换KDE Plasma
文章目录 安装KDE Plasma桌面环境添加软件源并更新apt安装kubuntu-desktop(作者没有成功)aptitude安装kubuntu-desktop多次aptitude install(特别重要特别重要)其他kde软件包 卸载gnome桌面 Ubuntu自带的桌面环境是gnomeÿ…...
Docker(九)Docker Buildx
作者主页: 正函数的个人主页 文章收录专栏: Docker 欢迎大家点赞 👍 收藏 ⭐ 加关注哦! Docker Buildx Docker Buildx 是一个 docker CLI 插件,其扩展了 docker 命令,支持 [Moby BuildKit] 提供的功能。提…...
Flink问题解决及性能调优-【Flink不同并行度引起sink2es报错问题】
最近需求,仅想提高sink2es的qps,所以仅调节了sink2es的并行度,但在调节不同算子并行度时遇到一些问题,找出问题的根本原因解决问题,并分析整理。 实例代码 --SET table.exec.state.ttl86400s; --24 hour,默认: 0 ms …...
瑞_数据结构与算法_二叉搜索树
文章目录 1 什么是二叉搜索树1.1 二叉搜索树的特征1.2 前驱后继 2 二叉搜索树的Java实现2.1 定义二叉搜索树节点类BSTNode泛型key改进 2.2 实现查找方法get(int key)递归实现非递归实现 ★非递归实现 泛型key版本 2.3 实现查找最小方法min()递归实现非递归实现 ★ 2.4 实现查找…...
Linux 命令行访问名字中包含空格的文件或文件夹
Linux 命令行访问名字中包含空格的文件或文件夹 References 在 Windows 下命名文件或文件夹名有空格是可以的,甚至在 Windows 和 Ubuntu 虚拟机共享的文件中也可以这么做,但是在 Ubuntu 中空格要用下划线代替,养成好习惯。Linux 会把空格当成…...
Dart/Flutter工具模块:the_utils
Flutter笔记 Dart/Flutter工具模块:the_utils 作者:李俊才 (jcLee95):https://blog.csdn.net/qq_28550263 邮箱 :291148484163.com 本文地址:https://blog.csdn.net/qq_28550263/article/detail…...
矩阵号:日入100+,八大提示词(Prompt)使用技巧
最近在搞头条矩阵,发现自己的指令写的太烂了,一个指令将会决定你的写作质量。 收益比较拉垮,50个号收益好的,也就这么几个号。 于是我扒了一些提示词的操作技巧,分享一下自己的学习心得。 先说理论知识,实…...
爬虫工作量由小到大的思维转变---<第三十九章 Scrapy-redis 常用的那个RetryMiddleware>
前言: 为什么要讲这个RetryMiddleware呢?因为他很重要~ 至少在你装配代理ip或者一切关于重试的时候需要用到!----最关键的是:大部分的教学视频里面,没有提及这个!!!! 正文: 源代码分析 这个RetryMiddleware是来自: from scrapy.downloadermiddlewares.retry import Retry…...
【MongoDB】mongodb安装及启动踩坑点
mongodb的安装,基本上参考文章[1]。 但是在过程中,有一些踩坑点。 1,高版本mongodb不自带mongo脚本 在文章1中,作者在解压后,直接使用了mongo脚本,而我下载的mongodb版本要更高,在解压后&…...
业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...
深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
HBuilderX安装(uni-app和小程序开发)
下载HBuilderX 访问官方网站:https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本: Windows版(推荐下载标准版) Windows系统安装步骤 运行安装程序: 双击下载的.exe安装文件 如果出现安全提示&…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...
