MySQL优化慢SQL的6种方式

⛰️个人主页:     蒾酒

🔥系列专栏《mysql经验总结》

🌊山高路远,行路漫漫,终有归途


目录

写在前面

优化思路

优化方法

1.避免查询不必要的列

2.分页优化

3.索引优化

4.JOIN优化

5.排序优化

6.UNION 优化

写在最后


写在前面

本文介绍了MySQL常见的优化慢sql的手段,坚持看完相信对你有帮助。

同时欢迎订阅MySQL系列专栏,持续分享MySQL的使用经验。

优化思路

慢sql的优化无非是从两个方向着手

  • SQL语句本身的优化
  • 据库设计的优化

下面进行渐进式的分享一些常见优化手段

优化方法

1.避免查询不必要的列

查询应该精准的查出需要的列,对于select * 的写法要避免,因为所有字段查出来不仅sql查询执行慢,若是直接返回给前端,大量的数据也会影响网络传输效率。

2.分页优化

对于数据量特别大,这时分页会比较深,查询扫描的数据量会比较大效率自然低,我们就需要进行分页优化

假设我们有一个包含大量订单记录的订单表,其中每个订单都有一个唯一的不包含业务逻辑的主键,并且我们想要查询最近一个月的订单并按照订单id从小到大进行分页显示某页。

假设出现深分页的sql如下:

select * from orders where order_date >= date_sub(now(), interval 1 month)order by id limit 100000, 10;

执行此SQL时需要先扫描到100000行,然后再去取10行,但是随着扫描的记录数越多,SQL的性能就会越差,因为扫描的记录越多,MySQL需要扫描越多的数据来定位到具体的多少行,这样耗费大量的 IO 成本和时间成本。

对于解决该深分页问题通常有两种方法

1.延迟关联

先通过 where 条件提取出主键,在将该表与原数据表关联,通过主键 id 提取数据行,而不是通过原来的二级索引提取数据行

优化后sql:

select o.*
from (select idfrom orderswhere order_date >= date_sub(now(), interval 1 month)order by idlimit 100000, 10
) as sub
join orders as o on sub.id = o.id;

优化后SQL中的子查询只取主键id,可避免通过二级索引中的主键去回表查询,这样性能会快一些。

2.id偏移量

偏移量就是找到 limit 第一个参数对应的主键值,根据这个主键值再去过滤并 limit,这种方法又称为基于游标的分页。基于游标的分页的前提是需要保证主键或排序列的连续性、唯一性。

优化后sql:

select *
from orders
where id >= (select id from orders order by id limit 100000, 1)
order by id
limit 10;

这种方法相对于原来直接使用偏移量和限制结果数量的方式,可以在大数据集上提供更稳定和一致的性能,因为它不需要扫描和跳过大量的行

3.索引优化

通过合理的设计和使用索引,能够有效优化sql性能,这也是我们使用最多的手段。

下面介绍一下如何进行索引优化:

使用覆盖索引

InnoDB使用二级索引查询数据时会回表,但是如果索引的叶节点中已经包含要查询的字段,那它没有必要再回表查询了,这就叫覆盖索引,还有一个简单的理解查询列都是索引列

示例:

select product_name, price
from products
where category_id = 1;
create index idx_category_id on products (category_id, product_name, price);

避免使用or查询

在 MySQL 5.0 之前的版本要尽量避免使用 or 查询,可以使用 union 或者子查询来替代,因为早期的MySQL版本使用 or 查询可能会导致索引失效,高版本引入了索引合并,解决了这个问题,不过建议大家在实际使用中还是规范写法,能不用就少用。

避免使用 != 或者 <>操作符

SQL中,不等于操作符会导致查询引擎放弃查询索引,引起全表扫描,即使比较的字段上有索引。解决方法:通过把不等于操作符改成 or,可以使用索引,避免全表扫描

id <>'aaa'
id >'aaa'or id<'aaa

适当使用前缀索引

适当地使用前缀索引,可以降低索引的空间占用,提高索引的查询效率。比如,邮箱的后缀都是固定的“@xxx.com”,那么类似这种后面几位为固定值的字段就非常适合定义为前缀索引

create index idx_email_prefix on users (email(6)); -- 假设后缀长度为6

需要注意的是,前缀索引也存在缺点,MySQL无法利用前缀索引做 order by和 group by 操作,也无法作为覆盖索引。

避免列上函数运算

要避免在列字段上进行算术运算或其他表达式运算,否则可能会导致存储引擎无法正确使用索引,从而影响了查询的效率。

select order_id
from orders
where total_amount / 2 > 100

正确使用联合索引

使用联合索引的时候,注意最左匹配原则。 

4.JOIN优化

优化子查询

尽量使用 Join 语句来替代子査询,因为子査询是嵌套查询,而嵌套查询会新创建一张临时表,而临时表的创建与销毁会占用一定的系统资源以及花费一定的时间,同时对于返回结果集比较大的子查询,其对查询性能的影响更大 

小表驱动大表

关联查询的时候要拿小表去驱动大表,因为关联的时候,MySQL内部会遍历驱动表,再去连接被驱动表

select name from小表 left join 大表;

适当增加冗余字段

增加冗余字段可以减少大量的连表查询,因为多张表的连表查询性能很低,所有可以适当的增加冗余字段,以减少多张表的关联查询,这是以空间换时间的优化策略。

避免使用 JOIN 关联太多的表

《阿里巴巴 Java 开发手册》规定不要 join 超过三张表,第一join 太多降低査询的速度,第二 join 的buffer 会占用更多的内存。

5.排序优化

利用索引扫描做排序

MYSQL有两种方式生成有序结果:一是对结果集进行排序的操作,二是按照索引顺序扫描得出的结果,索引是排好序的数据结构,自然是有序的。
但是如果索引不能覆盖查询所需列(覆盖索引),就会每扫描一条记录回表查询一次(逐个获取),这个读操作是随机 IO,通常会比顺序全表扫描还慢,有时会直接放弃使用索引转为全表扫描。因此,在设计索引时,尽可能使用同一个索引既满足排序又用于查找行。

#索引为 a,b,c
select b,c from test where a like 'aa%' order by b,c;

只有当索引的列顺序和 ORDER BY 子句的顺序完全一致,并且所有列的排序方向都一样时,才能够使用索引来对结果做排序。

6.UNION 优化

条件下推

MySQL处理 union 的策略是先创建临时表,然后将各个查询结果填充到临时表中最后再来做查询,很多优化策略在 union 查询中都会失效,因为它无法利用索引。所以需要将 where、limit 等子句下推到 union 的各个子查询中,以便优化器可以充分利用这些条件进行优化。

此外,除非确实需要服务器去重,一定要使用 union all,如果不加 all 关键字,MySQL 会给临时表加上distinct 选项,这会导致对整个临时表做唯一性检查,代价很高。

写在最后

MySQL优化慢SQL的6种方式到这里就结束了,本文介绍了常见慢sql优化的有效方式。任何问题评论区或私信讨论,欢迎指正。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

redis的设计与实现(五)——独立功能

1. Redis的其他功能 redis 除了简单对对象的增删改查的功能之外&#xff0c;其实还有其他高级功能&#xff0c;了解这些内容有利于我们更灵活的使用 redis 完成我们的业务功能。 2. 发布与订阅 2.1. 基本概念 很多中间件都有发布与订阅功能&#xff0c;但是&#xff0c;作为一…

软件无线电安全之GNU Radio基础 -上

GNU Radio介绍 GNU Radio是一款开源的软件工具集&#xff0c;专注于软件定义无线电&#xff08;SDR&#xff09;系统的设计和实现。该工具集支持多种SDR硬件平台&#xff0c;包括USRP、HackRF One和RTL-SDR等。用户可以通过GNU Radio Companion构建流程图&#xff0c;使用不同…

idea运行Tomcat,控制台日志的中文乱码

一 版本 win10&#xff0c;idea2022,jdk18,tomcat9 二 问题描述 在idea上可以运行Tomcat。服务器启动后&#xff0c;可以正常访问本地的html文件。但是控制台的Tomcat日志出现了乱码&#xff1a;server与Tomcat Catlina Log两处。 三 无效的解决之道 1 idea的Help选项Edit …

Python 全栈 Web 应用模板:成熟架构,急速开发 | 开源日报 No.223

tiangolo/full-stack-fastapi-template Stars: 15.6k License: MIT full-stack-fastapi-template 是一个现代化的全栈 Web 应用模板。 使用 FastAPI 构建 Python 后端 API。使用 SQLModel 进行 Python SQL 数据库交互&#xff08;ORM&#xff09;。Pydantic 用于数据验证和设…

2024最新数据分级分类的架构方法流程指南(附下载)

以下是资料目录&#xff0c;如需下载请前往知识星球下载&#xff1a;https://t.zsxq.com/18KTZnJMX ​ ​ ​​​​​​​​​​​​​ 以下是资料目录&#xff0c;如需下载请前往知识星球下载&#xff1a;https://t.zsxq.com/18KTZnJMX ​

Jmeter配置服务器监控插件

1.安装插件管理器 插件官网地址&#xff1a;JMeter Plugins :: JMeter-Plugins.org 点击 Plugins Manager,如上图所示&#xff0c; &#xff0c;点击jar file下载“plugins-manager.jar”&#xff0c;下载后放到“jmeter\lib\ext”目录下&#xff0c;重启jmeter。 2.安装资源…

Ubuntu-22.04安装Virtualbox并安装Windows10

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、Virtualbox是什么&#xff1f;二、安装Virtualbox1.关闭Secure Boot2.安装 三、安装Windows101.新装虚拟机基本配置2.新装虚拟机核心配置 总结 前言 虚拟机…

iOS------SDWebImage源码

一&#xff0c;简介 一个异步图片下载及缓存的库 特性&#xff1a; 一个扩展UIImageView分类的库&#xff0c;支持加载网络图片并缓存图片异步图片下载器异步图片缓存和自动图片有效期限管理支持GIF动态图片支持WebP背景图片减压保证同一个URL不会再次下载保证无效的URL不会…

InnoDB中高度为3的B+树最多可以存多少数据?

参考&#xff1a; &#x1f525;我说MySQL每张表最好不超过2000万数据&#xff0c;面试官让我回去等通知&#xff1f; - 掘金 考虑到磁盘IO是非常高昂的操作&#xff0c;计算机操作系统做了预读的优化&#xff0c;当一次IO时&#xff0c;不光把当前磁盘地址的数据&#xff0c;…

Linux 快问快答

如果对于找 Java 后端开发的话&#xff0c;我感觉会这几个差不多了&#xff0c;面试官应该不会问的这么详细吧。一般就问问 Linux 的几个常用的命令&#xff0c;然后做一些简单的性能排查就好了。如果面试被问到另外的问题&#xff0c;那我再补充进来&#xff0c;现在先掌握这么…

stm32开发之threadx+modulex组合开发使用记录

前言 参考博客 论坛官方资料: 微软开发板核心芯片使用的是stm32f407zgtx&#xff0c;烧录工具使用的是jlink模块的构建使用的是脚本进行构建网上针对modulex的资料较少&#xff0c;这里做个记录 项目结构 逻辑框架 主程序代码 主函数 /** Copyright (c) 2024-2024&#xff0…

Abstract Factory抽象工厂模式详解

模式定义 提供一个创建一系列相关或互相依赖对象的接口&#xff0c;而无需指定它们具体的类。 代码示例 public class AbstractFactoryTest {public static void main(String[] args) {IDatabaseUtils iDatabaseUtils new OracleDataBaseUtils();IConnection connection …

shell 调用钉钉通知

使用场景&#xff1a;机器能访问互联网&#xff0c;运行时间任务后通知使用 钉钉建立单人群 手机操作&#xff0c;只能通过手机方式建立单人群 电脑端 2. 配置脚本 #!/bin/bash set -e## 上图中 access_token字段 TOKEN KEYWORDhello # 前文中设置的关键字 function call_…

Java入门教程||Java 变量

Java 变量 Java教程 - Java变量 变量由标识符&#xff0c;类型和可选的初始化程序定义。变量还具有范围&#xff08;可见性/生存期&#xff09;。 Java变量类型 在Java中&#xff0c;必须先声明所有变量&#xff0c;然后才能使用它们。变量声明的基本形式如下所示&#xff1…

【Web】DASCTF X GFCTF 2022十月挑战赛题解

目录 EasyPOP hade_waibo EasyLove BlogSystem EasyPOP 先读hint.php sorry.__destruct -> secret_code::secret() exp: $anew sorry(); $bnew secret_code(); $a->password"suibian"; $a->name"jay"; echo serialize($a); 真暗号啊&…

RMAN数据迁移方案

数据迁移 Oracle环境检查 开启归档 1.首先关闭数据库 shutdown immediate; 2.打开mount状态 startup mount; 3.更改数据库为归档模式 alter database archivelog; 4.打开数据库 alter database open; 5.再次检查 archive log list; 查看构造的表和数据 由于数据会有中文&…

【微信小程序——案例——本地生活(列表页面)】

案例——本地生活&#xff08;列表页面&#xff09; 九宫格中实现导航跳转——以汽车服务为案例&#xff08;之后可以全部实现页面跳转——现在先实现一个&#xff09; 在app.json中添加新页面 修改之前的九宫格view改为navitage 效果图&#xff1a; 动态设置标题内容—…

SpringMVC--获取请求参数 / 域对象共享数据

目录 1. SpringMVC 获取请求参数 1.1. 通过ServletAPI获取 1.2. 控制器方法形参获取 1.3. RequestParam 1.4. RequestHeader 1.5. CookieValue 1.6. 通过POJO获取请求参数 1.7. 解决获取请求参数的乱码问题 2. 域对象共享数据 2.1. 三大域对象 2.2. 准备工作 2.3. S…

Linux awk

文章目录 1. 基础用法2. awk字符获取和筛选获取CPU/MEM占用率将awk指令包封脚本 3.awk条件与循环语句4.awk调用函数 1. 基础用法 操作粒度更加精细&#xff0c;可以以特殊字符&#xff08;: 空格等&#xff09;分割为列再进一步操作。例如 ps -aux获取到自己的进程后想进一步…

React+TS项目搭建

使用webpack5搭建ReactTS项目 一.初始化项目 初始化一个基本的reactts项目,首先创建一个项目文件夹,输入初始化命令 npm init -y 初始化完成后生成package.json文件,之后需要在项目下新增以下所示目录结构和文件 ├── build | ├── webpack.base.js # 公共配置 | ├…