MySQL—SQL优化详解(下)

news2024/11/25 10:31:45

♥️作者:小刘在C站

♥️个人主页: 小刘主页 

♥️努力不一定有回报,但一定会有收获加油!一起努力,共赴美好人生!

♥️学习两年总结出的运维经验,以及思科模拟器全套网络实验教程。专栏:云计算技术

♥️小刘私信可以随便问,只要会绝不吝啬,感谢CSDN让你我相遇!

前言

本章讲解SQL语言中的优化,有想看上章的小伙伴可以到小刘主页进行查看,因为有一些原因我提供不了链接。

目录

3 order by优化

A. 数据准备

 B. 执行排序SQL

C. 创建索引

D. 创建索引后,根据age, phone进行升序排序

E. 创建索引后,根据age, phone进行降序排序

F. 根据phone,age进行升序排序,phone在前,age在后。

F. 根据age, phone进行降序一个升序,一个降序

G. 创建联合索引(age 升序排序,phone 倒序排序)

 H. 然后再次执行如下SQL

4 group by优化

5 limit优化

6 count优化

6.1 概述

6.2 count用法

7 update优化


3 order by优化

MySQL 的排序,有两种方式:
Using filesort : 通过表的索引或全表扫描,读取满足条件的数据行,然后在排序缓冲区 sort
buffer 中完成排序操作,所有不是通过索引直接返回排序结果的排序都叫 FileSort 排序。
Using index : 通过有序索引顺序扫描直接返回有序数据,这种情况即为 using index ,不需要
额外排序,操作效率高。
对于以上的两种排序方式, Using index 的性能高,而 Using filesort 的性能低,我们在优化排序
操作时,尽量要优化为 Using index
接下来,我们来做一个测试:

A. 数据准备

把之前测试时,为 tb_user 表所建立的部分索引直接删除掉
drop index idx_user_phone on tb_user;
drop index idx_user_phone_name on tb_user;
drop index idx_user_name on tb_user;

 B. 执行排序SQL

explain select id,age,phone from tb_user order by age ;

explain select id,age,phone from tb_user order by age, phone ;

由于 age, phone 都没有索引,所以此时再排序时,出现 Using filesort , 排序性能较低。

C. 创建索引

-- 创建索引
create index idx_user_age_phone_aa on tb_user(age,phone);

D. 创建索引后,根据age, phone进行升序排序

explain select id,age,phone from tb_user order by age;

 explain select id,age,phone from tb_user order by age , phone; 

建立索引之后,再次进行排序查询,就由原来的 Using filesort , 变为了 Using index ,性能
就是比较高的了。

E. 创建索引后,根据age, phone进行降序排序

explain select id,age,phone from tb_user order by age desc , phone desc ;

也出现 Using index , 但是此时 Extra 中出现了 Backward index scan ,这个代表反向扫描索
引,因为在 MySQL 中我们创建的索引,默认索引的叶子节点是从小到大排序的,而此时我们查询排序 时,是从大到小,所以,在扫描时,就是反向扫描,就会出现 Backward index scan 。 在
MySQL8 版本中,支持降序索引,我们也可以创建降序索引。

F. 根据phoneage进行升序排序,phone在前,age在后。

explain select id,age,phone from tb_user order by phone , age;

排序时 , 也需要满足最左前缀法则 , 否则也会出现 filesort 。因为在创建索引的时候, age 是第一个
字段, phone 是第二个字段,所以排序时,也就该按照这个顺序来,否则就会出现 Using
filesort

F. 根据age, phone进行降序一个升序,一个降序

explain select id,age,phone from tb_user order by age asc , phone desc ; 

 因为创建索引时,如果未指定顺序,默认都是按照升序排序的,而查询时,一个升序,一个降序,此时就会出现Using filesort

 

为了解决上述的问题,我们可以创建一个索引,这个联合索引中 age 升序排序, phone 倒序排序。

G. 创建联合索引(age 升序排序,phone 倒序排序)

create index idx_user_age_phone_ad on tb_user(age asc ,phone desc);

 H. 然后再次执行如下SQL

explain select id,age,phone from tb_user order by age asc , phone desc ;

 升序/降序联合索引结构图示:

 

由上述的测试 , 我们得出 order by 优化原则 :
A. 根据排序字段建立合适的索引,多字段排序时,也遵循最左前缀法则。
B. 尽量使用覆盖索引。
C. 多字段排序 , 一个升序一个降序,此时需要注意联合索引在创建时的规则( ASC/DESC )。
D. 如果不可避免的出现 filesort ,大数据量排序时,可以适当增大排序缓冲区大小
sort_buffer_size( 默认 256k)

4 group by优化

分组操作,我们主要来看看索引对于分组操作的影响。
首先我们先将 tb_user 表的索引全部删除掉 。
drop index idx_user_pro_age_sta on tb_user;
drop index idx_email_5 on tb_user;
drop index idx_user_age_phone_aa on tb_user;
drop index idx_user_age_phone_ad on tb_user;

 接下来,在没有索引的情况下,执行如下SQL,查询执行计划:

explain select profession , count(*) from tb_user group by profession ; 

 然后,我们在针对于 profession agestatus 创建一个联合索引。

create index idx_user_pro_age_sta on tb_user(profession , age , status); 
紧接着,再执行前面相同的 SQL 查看执行计划。
explain select profession , count(*) from tb_user group by profession ;

 再执行如下的分组查询SQL,查看执行计划:

我们发现,如果仅仅根据 age 分组,就会出现 Using temporary ;而如果是 根据
profession,age 两个字段同时分组,则不会出现 Using temporary 。原因是因为对于分组操作,
在联合索引中,也是符合最左前缀法则的。
所以,在分组操作中,我们需要通过以下两点进行优化,以提升性能:
A. 在分组操作时,可以通过索引来提高效率。
B. 分组操作时,索引的使用也是满足最左前缀法则的。

5 limit优化

在数据量比较大时,如果进行 limit 分页查询,在查询时,越往后,分页查询效率越低。
我们一起来看看执行 limit 分页查询耗时对比:

 通过测试我们会看到,越往后,分页查询效率越低,这就是分页查询的问题所在。

因为,当在进行分页查询时,如果执行 limit 2000000,10 ,此时需要 MySQL 排序前 2000010
录,仅仅返回 2000000 - 2000010 的记录,其他记录丢弃,查询排序的代价非常大 。
优化思路 : 一般分页查询时,通过创建 覆盖索引 能够比较好地提高性能,可以通过覆盖索引加子查
询形式进行优化.
explain select * from tb_sku t , (select id from tb_sku order by id
limit 2000000,10) a where t.id = a.id;

6 count优化

6.1 概述

select count(*) from tb_user ;
在之前的测试中,我们发现,如果数据量很大,在执行 count 操作时,是非常耗时的。
MyISAM 引擎把一个表的总行数存在了磁盘上,因此执行 count(*) 的时候会直接返回这个
数,效率很高; 但是如果是带条件的 count MyISAM 也慢。
InnoDB 引擎就麻烦了,它执行 count(*) 的时候,需要把数据一行一行地从引擎里面读出
来,然后累积计数。
如果说要大幅度提升 InnoDB 表的 count 效率,主要的优化思路:自己计数 ( 可以借助于 redis 这样的数据库进行 , 但是如果是带条件的 count 又比较麻烦了 )

6.2 count用法

count() 是一个聚合函数,对于返回的结果集,一行行地判断,如果 count 函数的参数不是
NULL ,累计值就加 1 ,否则不加,最后返回累计值。
用法: count * )、 count (主键)、 count (字段)、 count (数字)

 按照效率排序的话,count(字段) < count(主键 id) < count(1) ≈ count(*),所以尽

量使用 count(*)

7 update优化

我们主要需要注意一下 update 语句执行时的注意事项。
update course set name = 'javaEE' where id = 1 ; 
当我们在执行删除的 SQL 语句时,会锁定 id 1 这一行的数据,然后事务提交之后,行锁释放.
但是当我们在执行如下 SQL 时。
update course set name = 'SpringBoot' where name = 'PHP' ;
当我们开启多个事务,在执行上述的 SQL 时,我们发现行锁升级为了表锁。 导致该 update 语句的性能大大降低。
InnoDB 的行锁是针对索引加的锁,不是针对记录加的锁 , 并且该索引不能失效,否则会从行锁升级为表锁

♥️关注,就是我创作的动力

♥️点赞,就是对我最大的认可

♥️这里是小刘,励志用心做好每一篇文章,谢谢大家

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

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

相关文章

FFmpeg 内存模型分析

标题 1. 内存模型图2. 分析流程3.追溯本源————源码分析3.1 AVPacket队列 什么时候生成的&#xff1f; 4 .AVPacket和AVFrame相关操作API5. av_read_frame源码分析 1. 内存模型图 2. 分析流程 我们解复用后,媒体流数据就会被分离开来,分别生成对应AVPacketList,然后通过av_…

BART论文解读

1 概述 全称&#xff1a;Denoising Sequence-to-Sequence Pre-training for Natural Language Generation, Translation, and Comprehension。BART来源于Bidirectional and Auto-Regressive Transformers发表时间: 2019.10.29团队&#xff1a;Facebook AI Paper地址​arxiv.o…

chatgpt赋能python:Python怎么求解方程

Python怎么求解方程 在数学中&#xff0c;求解方程是一种基本的技能。Python作为一种广泛应用于科学计算和数据分析领域的编程语言&#xff0c;可以帮助我们求解各种类型的方程。Python提供了多个库和函数&#xff0c;使得求解方程在Python中变得非常轻松。 一元方程求解 一…

Android Framework分析SystemServer进程

SystemServer进程是Android系统的核心进程&#xff0c;运行在Android系统启动后&#xff0c;负责管理和加载系统服务。本文将介绍SystemServer进程的详细结构和工作原理&#xff0c;并使用代码注释的方式阐述其关键部分代码。 结构&#xff1a; SystemServer进程的核心是Syste…

SSH基本概念,带你了解SSH

1、SSH基本概念 SSH&#xff08;Secure Shell&#xff09;是一种网络协议&#xff0c;用于在不安全的网络中安全地传输数据。它是一种加密协议&#xff0c;可以保护数据在传输过程中不被窃取、篡改或伪造。SSH协议最初是由芬兰的Tatu Ylonen开发的&#xff0c;现在已经成为了一…

Hadoop集群之模板虚拟机的安装

Hadoop集群之模板虚拟机的安装 文章目录 Hadoop集群之模板虚拟机的安装0. 写在前面1. CentOS的安装1.1 配置电脑1.1.1 进入VMware1.1.2 自定义新的虚拟机1.1.3 解决虚拟机的兼容性1.1.4 选择当前虚拟机的操作系统1.1.5 选择虚拟机将来需要安装的系统1.1.6 电脑的具体配置1.1.7 …

KUKA机器人通过示教器进行关机冷启动的具体方法演示

KUKA机器人通过示教器进行关机冷启动的具体方法演示 如下图所示,首先需要登录管理员权限,默认密码:KUKA,然后点击左上角的机器人图标进行菜单选项,找到并点击“关机”选项, 如下图所示,找到并点击“重新启动控制系统PC”, 如下图所示,此时系统提示:确实要重新启动…

chatgpt赋能python:Python生成序列的方法详解

Python生成序列的方法详解 在Python编程中&#xff0c;序列&#xff08;Sequence&#xff09;是常用的数据类型之一。序列是有序的&#xff0c;可以通过下标访问其中的元素。Python中有多种方法可以生成序列&#xff0c;下面将对常用的几种方法进行详细介绍。 利用range函数生…

2023-06-16 Android Studio 使用CMakeList编译JNI ,最简单的demo源码

一、代码结构图&#xff0c;代码路径https://download.csdn.net/download/qq_37858386/87913001 二、cmakedemo\app\build.gradle 加下面的代码 externalNativeBuild {cmake {cppFlags "-frtti -fexceptions"}}externalNativeBuild {cmake {path src/main/jni/CMakeL…

国内大模型研究

自从chatgpt发布以来&#xff0c;国内大模型发展非常迅速。我对这项目技术也保持了非常多的持续关注&#xff0c;我一直认识&#xff0c;chatGPT以及其他GPT会给社会带来更大的变革。经过专业训练的大模型可以替代部分客服&#xff0c;部分程序员&#xff0c;部分美工&#xff…

Vue全家桶实战 从零独立开发企业级电商系统(免费升级Vue3.0)

Vue全家桶高仿小米商城–项目简介 文章目录 Vue全家桶高仿小米商城--项目简介电商项目选型--小米商城的页面流程&#xff1a;业务开发流程&#xff1a;项目内容&#xff1a;商城组件部分&#xff1a;课程所包含的知识图谱&#xff1a;章节介绍&#xff1a; 商城的界面展示&…

基于web漏洞扫描及分析系统设计_kaic

基于web漏洞扫描及分析系统设计 摘 要 随着信息技术的发展和网络应用在我国的普及&#xff0c;针对我国境内信息系统的恶意网络攻击也越来越多&#xff0c;并且随着黑客攻击技术的不断地更新&#xff0c;网络犯罪行为变得越来越难以应对&#xff0c;用户日常访问的网站是否安全…

【八大排序(六)】快排终极篇-快速排序非递归版

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:八大排序专栏⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习排序知识   &#x1f51d;&#x1f51d; 快排非递归版 1. 前情回顾2. 快排非递归基…

A100 GPU服务器安装CUDNN教程

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

从Window中先多瞥几眼

JavaFx17官方文档中有如下的描述: Window类是一个顶层窗口类,在其中可以承载场景,并与用户交互。窗口可以是Stage、PopupWindow或其他类似的顶层窗口。 JavaFX Stage类是顶级的JavaFX容器。初级阶段由平台搭建。其他Stage对象可以由应用程序构造。 许多Stage属性是只读的…

chatgpt赋能python:Python入门:如何添加Seaborn库

Python入门&#xff1a;如何添加Seaborn库 Python是一种易于学习的、功能强大的编程语言&#xff0c;在数据分析和科学计算方面尤其闻名。Seaborn是一个建立在Matplotlib之上的Python可视化库&#xff0c;它提供了一组简单易用的界面&#xff0c;用于绘制优美的统计图形——包…

几个Caller-特性的妙用

System.Runtime.CompilerServices命名空间下有4个以“Caller”为前缀命名的Attribute&#xff0c;我们可以将它标注到方法参数上自动获取当前调用上下文的信息&#xff0c;比如当前的方法名、某个参数的表达式、当前源文件的路径&#xff0c;以及当前代码在源文件中的行号。 一…

RedisSon高并发分布式锁实战RedisSon源码解读

Redis高并发分布式锁实战 1.分布式场景下的synchronized失效的问题–用redis实现分布式锁 synchronized是通过monitor实现的jvm级别的锁&#xff0c;如果是分布式系统&#xff0c;跑在不同的虚拟机上的tomcat上&#xff0c;会导致synchronized无法锁住对象 ----------- 需要分…

读数据压缩入门笔记05_字典转换

1. 瓶颈 1.1. 在网络带宽有限、存储昂贵的时期 1.2. 移动设备正日益成为人们访问互联网的首选的今天 1.3. 数据压缩成了缓解这些瓶颈的关键 2. 字典转换 2.1. dictionary transforms 2.2. 完全改变了人们对数据压缩的认知 2.2.1. 压缩变成了一种对各种类型的数据都有用的…

《C和指针》读书笔记(第十一章 动态内存分配)

目录 0 简介1 为什么使用动态内存分配2 malloc和free3 calloc和realloc4 使用动态分配的内存5 常见的动态内存错误6 内存分配实例6.1 排序一列整型值6.2 复制字符串6.3 变体记录的创建与销毁 7 总结 0 简介 在实际开发中&#xff08;C语言&#xff09;&#xff0c;数组的元素存…