Mysql进阶(中) -- 索引

news2024/11/22 22:27:18

索引上部分 -> Mysql进阶(上) -- 存储引擎,索引_千帐灯无此声的博客-CSDN博客 

👂 爸爸妈妈 - 王蓉 - 单曲 - 网易云音乐

👈目录看左栏

目录

🌼索引

🐻性能分析 - show profiles

🐻性能分析 - explain

🍌使用规则 - 验证索引效率

🍌使用规则 - 最左前缀法则

🍌使用规则 - 索引失效情况1

🍌使用规则 - 索引失效情况2

🍌使用规则 - SQL提示

🍌使用规则 - 覆盖索引&回表查询

🍌使用规则 - 前缀索引

🍌使用规则 - 单列&联合索引

🍉设计原则

🍉小结


🌼索引

🐻性能分析 - show profiles

开关未开启👇

打开开关👇

突然,出现了BUG👇

为此我专门写了一篇文章 -> Finalshell连接Linux超时之Connection timed out: connect_千帐灯无此声的博客-CSDN博客

开关打开后,开始查询👇

查看每一条SQL语句的耗时👇

根据name查询比根据id查询慢很多👆

查询指定SQL语句👇

查询指定SQL语句CPU使用情况👇

🐻性能分析 - explain

Datagrip,创建3个表👇

use itcast;


create table student(
    id   int auto_increment comment '主键ID' primary key,
    name varchar(10) null comment '姓名',
    no   varchar(10) null comment '学号'
)comment '学生表';

INSERT INTO student (name, no) VALUES ('黛绮丝', '2000100101');
INSERT INTO student (name, no) VALUES ('谢逊', '2000100102');
INSERT INTO student (name, no) VALUES ('殷天正', '2000100103');
INSERT INTO student (name, no) VALUES ('韦一笑', '2000100104');



create table course(
    id int auto_increment comment '主键ID' primary key,
    name varchar(10) null comment '课程名称'
)comment '课程表';

INSERT INTO course (name) VALUES ('Java');
INSERT INTO course (name) VALUES ('PHP');
INSERT INTO course (name) VALUES ('MySQL');
INSERT INTO course (name) VALUES ('Hadoop');



create table student_course(
    id int auto_increment comment '主键' primary key,
    studentid int not null comment '学生ID',
    courseid  int not null comment '课程ID',
    constraint fk_courseid foreign key (courseid) references course (id),
    constraint fk_studentid foreign key (studentid) references student (id)
)comment '学生课程中间表';

INSERT INTO student_course (studentid, courseid) VALUES (1, 1);
INSERT INTO student_course (studentid, courseid) VALUES (1, 2);
INSERT INTO student_course (studentid, courseid) VALUES (1, 3);
INSERT INTO student_course (studentid, courseid) VALUES (2, 2);
INSERT INTO student_course (studentid, courseid) VALUES (2, 3);
INSERT INTO student_course (studentid, courseid) VALUES (3, 4);

Datagrip中,右键student_course,打开Diagram可视化👇

3张表联查,需要2个where来消除无效笛卡尔积👇 

查询所有学生选修的课程👇

查询连接顺序👇

查询选修了Mysql的学生👇

(1)分3步实现

(2)子查询1步实现👇

类似的,自己可以再写一个,查询韦一笑选修了什么课程👇

先逐步拆分👇

再子查询👇  --  书写顺序是:先进入course表,再进入中间表,最后进入student表

(1)course

(2)student_course

(3)student

再用explain / desc看看执行顺序👇

但是执行顺序和书写顺序不同

执行顺序,先执行内层,也就是先student,再course,最后中间表

id越大,越先执行;id相同,按顺序执行

explain各字段含义👇

再讲下type👇

根据 主键 或 唯一索引 访问,才会出现const👇比如

唯一索引👇

所以select时,尽量防止出现all,all代表全表扫描,性能较低

再讲下possible_key

最后讲下👇

需要重点关注的字段👇

尤其是type,作为性能指标 

🍌使用规则 - 验证索引效率

加个  \G ,查询字段以 row 的方式显示 

 执行show index from tb_sku; 后,发现没有 sn 的索引,所以查询1条记录的时间相当于查询 * 的时间,下面我们需要创建 sn 的索引👇

创建耗时 49s ,因为创建索引,实际上是给 800万条数据,构造B+Tree的过程

再次查询👇

从 18s 提升到了 0.02s

接着explain查看索引👇

sn 这个字段使用了索引 

🍌使用规则 - 最左前缀法则

不跳过索引中的列👆

show index👇可以看到3个索引的顺序

查询👇

去掉结尾 status 再次查询👇

👆最左边的字段 profession 存在,并且没有跳过中间的列

继续查询

这次跳过 profession(索引最左边的列),索引全部失效👇

而且 type = all,全表扫描👆,因为不满足最左前缀法则

进行个对比

(1)

(2) 

索引长度一样,说明(1)没有走 status 的索引,因为不满足最左前缀法则,中间跳过了 age 的索引,所以索引部分失效

possible_keys可能的索引,key实际使用的索引

当顺序改变时,索引长度不变,满足最左前缀法则👇

除了 最左前缀法则,还有 范围查询👇

(1)由索引长度,status 失效了

(2)当 > 改成 >= , status生效

所以,一般业务中,尽量使用 >=, <=,而不是 >

🍌使用规则 - 索引失效情况1

在索引列上进行 运算,索引列会失效,全表扫描👇

substring截取字串,第二个参数,下标从1开始 

 

可能用到的索引,用了;但实际的 key,没用到,还是全表扫描

尾部模糊匹配

头部模糊匹配

总之前面不能加 % 和 _,大数据查询下,会全表扫描,大数据下性能较低

🍌使用规则 - 索引失效情况2

创建age索引👇

如果Mysql评估走索引比全表扫描慢,则不走索引

当profession置空,结果会反过来👇

走不走索引,主要看is null 或 is not null占少数还是多数,少数就会走索引

多数的话,Mysql默认不如全表扫描,会直接全表扫描,所以不走索引

🍌使用规则 - SQL提示

注意,为了恢复profession,不是删表再重新插入,而是清空再insert,否则之前创建的联合索引等,还得重新创建👇

create index idx_user_name on tb_user(name);
 
create unique index idx_user_phone on tb_user(phone);
 
create index idx_user_pro_age_sta on tb_user(profession,age,status);
 
create index idx_user_age on tb_user(age);

create index idx_user_email on tb_user(email);

给profession创建单列索引👇

一个单列,一个联合索引,Mysql选择了联合索引👇

提示Mysql到底用哪个索引👇

use用,ignore不用,force必须用,跟在表名后

🍌使用规则 - 覆盖索引&回表查询

一般using index condition对应select *

而using where; using index对应具体的select

(1)

(2)

(1)需要回表查询,效率较低,(2)不需要

因为pro, age, status的联合索引,属于二级索引,二级索引叶子节点挂的是id,此时(2)中直接查询二级索引,就得到了需要的数据

但是(1)中name字段,不在这个二级索引中,还要到id的聚集索引中查找

关于聚集索引,二级索引和回表查询,可以看👇文章中,索引-分类这一部分

Mysql进阶(上) -- 存储引擎,索引_千帐灯无此声的博客-CSDN博客

覆盖索引,通俗点讲,就是只需要查询一次,通过索引本身可以满足查询需求。

覆盖索引不需要回表查询。

至于上面提到的,覆盖索引时,避免使用 select *,是因为,容易发生回表查询,除非创建联合索引,而查询的列正好是联合索引包含的列和id

一道面试题👇

如何简历索引,建立怎样的索引,才能是最优方案呢👇

答:根据username, password两个字段,建立联合索引(二级索引),而二级索引叶子下挂的就是id,即覆盖索引,不需要回表查询

🍌使用规则 - 前缀索引

例如,计算email的选择性👇

记录总数24👇

不重复的email也是24👇

所以email的选择性 = 24 / 24 = 1👇

观察前缀索引,先截取前10个字符,节约索引空间👇

截取前9个👇

直到.....👇

截取到前5个,依然是9583

针对email建立前缀索引

两个5表示,对email取5个前缀

Sub_part表示截取字段

前缀索引使用👇

大文本或长字符串,采取前缀索引,降低索引体积,提高查询效率,避免对磁盘IO的浪费

前缀索引查询流程

首先,主键id会创建聚集索引,我们再创建前缀索引

截取前5个字符是因为,区分度已经足够高

👆逐个匹配,比如 lvbu6,l比d大,所以往右走,来到lvbu6.........

到了叶节点,拿到对应数据后,我们还得对整个email进行对比.....

🍌使用规则 - 单列&联合索引

补充:键盘右上角,Home键定位命令行头,Ended键定位尾部。

下面解释为什么,多个联合条件时,推荐使用,联合索引👇

创建联合索引

执行下列语句

extra为Null,表示回表查询了👇因为单列索引和联合索引都存在时,默认单列

当我们建议Mysql使用联合索引👇

Using index表示覆盖索引,不需要回表查询

联合索引情况👇

注意,创建联合索引时,需要考虑字段顺序,根据最左前缀法则,最左边的列,必须非空,否则索引会失效

🍉设计原则

(1)比如,100万条数据,就需要建立索引,而几千几万条数据是不需要的

(3)区分度指的是,比如身份证,姓名,部门,区分度最高的是身份证

(4)大文本,长字符串,需要建立前缀索引(也需要考虑区分度)

(5)尽量使用联合索引,可以覆盖索引,避免回表

(6)只建立有必要的索引,降低维护成本

🍉小结

--

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/846185.html

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

相关文章

Cocos 适配 HarmonyOS NEXT,亮相 HDC2023,携手华为共筑鸿蒙生态!

HDC 2023 8月4-6日&#xff0c;作为华为合作伙伴&#xff0c;Cocos 引擎应邀参加了华为开发者大会 2023 - HDC 2023 暨 HarmonyOS 4 发布会&#xff0c;并获得了【鸿蒙生态能力共创奖】。 8月5日&#xff0c;在华为开发者大会&#xff08;HDC.Together&#xff09;游戏服务论坛…

SpringBoot系列---【使用jasypt把配置文件密码加密】

使用jasypt把配置文件密码加密 1.引入pom坐标 <dependency><groupId>com.github.ulisesbocchio</groupId><artifactId>jasypt-spring-boot-starter</artifactId><version>3.0.5</version> </dependency> 2.新增jasypt配置 2.1…

HCIP-linux知识

linux安装教程参考&#xff0c;https://blog.51cto.com/cloudcs/5245337 yum源配置 本地yum源配置&#xff1a; 8版本配置&#xff1a;将光盘iso挂载到某个目录&#xff0c;/dev/cdrom是/dev/sr0软链接&#xff0c;# mount /dev/cdrom /mnt&#xff0c;# ls /mnt AppStream B…

Elastic:linux设置elasticsearch、kibana开机自启

0. 引言 每次启动服务器都要手动启动es服务&#xff0c;相当之不方便&#xff0c;为此&#xff0c;书写一个脚本&#xff0c;实现es、kibana的开机自启 1. 原理 首先任何服务要实现开机自启&#xff0c;都可分为如下三步&#xff1a; 1、在/etc/init.d目录下创建启动、关闭服…

跳表与Redis

跳表原理 跳表是Redis有序集合ZSet底层的数据结构 首先有一个头结点 这个头结点里面的数据是null 就是他就是这个链表的最小值 就算是Math.Min也比它大 然后我们新建一个节点的时候是怎么操作的呢 先根据参数(假如说是5)创建一个节点 然后把它放在对应位置 就是找到小于他的最…

(JS逆向专栏十一)某融平台网站登入RSA

声明: 本文章中所有内容仅供学习交流&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff0c;若有侵权&#xff0c;请联系我立即删除&#xff01; 名称:点融 目标:登入参数 加密类型:RSA 目标网址:https://www.dianrong.com/accoun…

java: 无法访问org.springframework.web.bind.annotation.GetMapping(springboot构建时出现问题)

spring boot构建完成后出现以下问题 报错原因&#xff1a;SpringBoot 3.0以上版本要求JDK 17以上&#xff0c;jdk版本1.8 与 spring boot 3.0.1 版本不匹配 解决方法&#xff1a;

ORA-48913: Writing into trace file failed, file size limit [50000000] reached

检查某环境的alert_orcl1.log时&#xff0c;发现有很多的ORA-48913报错&#xff0c;细节如下 Sat Jul 22 19:34:04 2023 Non critical error ORA-48913 caught while writing to trace file "/u01/app/oracle/diag/rdbms/orcl/orcl1/trace/orcl1_dw00_138010.trc" E…

Python 中的机器学习简介:多项式回归

一、说明 多项式回归可以识别自变量和因变量之间的非线性关系。本文是关于回归、梯度下降和 MSE 系列文章的第三篇。前面的文章介绍了简单线性回归、回归的正态方程和多元线性回归。 二、多项式回归 多项式回归用于最适合曲线拟合的复杂数据。它可以被视为多元线性回归的子集。…

BenchmarkSQL 支持 TiDB 驱动以及 tidb-loadbalance

作者&#xff1a; GangShen 原文来源&#xff1a; https://tidb.net/blog/3c274180 使用 BenchmarkSQL 对 TiDB 进行 TPC-C 测试 众所周知 TiDB 是一个兼容 MySQL 协议的分布式关系型数据库&#xff0c;用户可以使用 MySQL 的驱动以及连接方式连接 TiDB 进行使用&#xff0…

Butterfly安装文档(三)主题配置-1

语言 修改站点配置文件 _config.yml 默认语言是 en 主题支持三种语言 default(en)zh-CN (简体中文)zh-TW (繁体中文) 网站资料 修改网站各种资料&#xff0c;例如标题、副标题和邮箱等个人资料&#xff0c;请修改博客根目录的_config.yml 导航栏设置 (Navigation bar set…

Data analysis|Tableau基本介绍及可实现功能

一、基础知识介绍 &#xff08;一&#xff09;什么是tableau tableau 成立于 2003 年&#xff0c;是斯坦福大学一个计算机科学项目的成果&#xff0c;该项目旨在改善分析流程并让人们能够通过可视化更轻松地使用数据。Tableau可以帮助用户更好地理解和发现数据中的价值&#x…

工具推荐之不出网环境下上线CS

前言 在实战攻防演练中&#xff0c;我们经常会遇到目标不出网的情况&#xff0c;即便获取了目标权限也不方便在目标网络进行下一步横向移动。本期我们将会推荐两个常用的代理工具&#xff0c;使我们能在不出网的环境下让目标上线到CS&#xff0c;方便后渗透的工作。 工具1&…

vue如何对node_modules源码进行修改,对第三方依赖包源码修改

方法 用patch-package给node_module中的包打补丁&#xff0c;解决修改源码的问题 使用 1、下载 patch-package 包&#xff1a;npm install patch-package -D 2、package.json文件中增加命令&#xff1a;"postinstall": "patch-package" {"scripts&quo…

【go-zero】docker镜像直接部署go-zero的API与RPC服务 如何实现注册发现?docker network 实现 go-zero 注册发现

一、场景&问题 使用docker直接部署go-zero微服务会发现API无法找到RPC服务 1、API无法发现RPC服务 用docker直接部署 我们会发现API无法注册发现RPC服务 原因是我们缺少了docker的network网桥 2、系统内查看 RPC服务运行正常API服务启动,通过docker logs 查看日志还是未…

MyCat垂直分库案例以及全局表概念讲解

这里的分片指的就是分库分表 1.垂直拆分 1.1场景介绍 1.2 数据库准备 1.3MyCat配置 schema.xml: <schema name"shopping" checkSQLschema"true" sqlMaxLimit"100"><table name"tb_goods_base" dataNode"dn1" pr…

⛳ Java注解

目录 ⛳ Java注解&#x1f3ed; 一&#xff0c;常见的注解&#x1f3a8; 二&#xff0c;JDK元注解&#x1f69c; 三&#xff0c;通过反射获取注解&#x1f43e; 3.1、JDK常用注解&#x1f463; 3.2、简单注解&#x1f4e2; 3.3、复杂注解 ⛳ Java注解 从 JDK 5.0 开始, Java 增…

python --windows获取启动文件夹路径/获取当前用户名/添加自启动文件

如何使用Python获取计算机用户名 一、Python自带的getpass模块可以用于获取用户输入的密码&#xff0c;但是它同样可以用来获取计算机用户名。 import getpassuser getpass.getuser() print("计算机用户名为&#xff1a;", user)二、使用os模块获取用户名 Python的…

深度学习部署:FastDeploy部署教程(CSharp版本)

FastDeploy部署教程(CSharp版本) 1. FastDeploy介绍 FastDeploy是一款全场景、易用灵活、极致高效的AI推理部署工具&#xff0c; 支持云边端部署。提供超过 &#x1f525;160 Text&#xff0c;Vision&#xff0c; Speech和跨模态模型&#x1f4e6;开箱即用的部署体验&#xf…

[机器学习]线性回归模型

线性回归 线性回归&#xff1a;根据数据&#xff0c;确定两种或两种以上变量间相互依赖的定量关系 函数表达式&#xff1a; y f ( x 1 , x 2 . . . x n ) y f(x_1,x_2...x_n) yf(x1​,x2​...xn​) ​ 回归根据变量数分为一元回归[ y f ( x ) yf(x) yf(x)]和多元回归[ y …