Mysql进阶SQL优化

        SQL优化在开发场景中必不可少的技能之一,它能最大限度的提升SQL查询性能,如果随意使用也会出现不可预料的结局。

1、为什么要优化SQL

        我们先说说不优化SQL造成什么现象。常见问题是响应时间长,用户体验感低。数据库频繁争抢锁,浪费性能。CPU过载,资源消耗高等问题。为了避免这些问题,不能盲目的添加资源,尽可能做到物尽其用。现实生活中不管对于ToC还是ToB,对外核心点:体验感永远是排在第一位,不管系统好坏,一旦体验感不行,都会丧失客户,这也是我们需要去优化SQL的原因之一。

        优化SQL旨在保证提高数据库性能,提升应用程序响应速度,提升体验感。

2、怎么优化SQL

2.1、开启慢查询

a)查看Mysql是否开启慢查询,一般默认没有开启

## 查看慢查询开关命令
show variables like 'slow_query_log';

b)开启慢查询日志

1、在Mysql安装目录中找到my.ini文件

2、添加以下参数:

## 开启慢查询
slow_query_log = 1
## 存放目录
slow_query_log_file = D:\developDoc\slowQueryLog\slowlog.log
## 执行时间超过多少秒(单位秒)就会被记录到慢查询日志中
long_query_time = 1

3、重启Mysql服务。

## windows环境
1、services.msc
2、查询Mysql服务。
3、点击重启即可## linux环境
systemctl restart mysqld;

4、查询是否开启与存放路径。

b)查询语句(根据自身需求书写SQL)

c)查看慢查询日志

2.2、Profiling耗时分析(非必须)

        后续补充。

2.3、语句分析

        语句分析有两种命令方式:explain(常用),desc(一般用于查看表结构);除了关键字外不一样,其他的都一样。

2.3.1、Explain/Desc

        我们先看看explain执行语句长什么样子。在分析他们之间的关系与含义。

        图中可以看到 id, select_type,table,partitions,type,possible_keys,key,key_len,ref,rows,filtered,extra 这些字段,下面将分开讲述这些字段。

        SQL分析中必须查看 type、possible_keys、key、extra 四列,ken_len 其次,其他的可以根据需求查看。

2.3.1.1、id

        id:序号值,旨在控制执行顺序,值越大越先执行,值相同从上到下执行。

单行时,不用关注id数值,多行顺序值,需要关注执行顺序来分析SQL信息。

例如:

        查询中国银行中有多少用户,并提取用户信息。

select*
fromd_user du
wheredu.user_id in (selectdba.user_idfromd_bank_account dbawheredba.user_id = du.user_idand dba.bank_id = (selectdb.bank_idfromd_bank dbwheredb.bank_name = '中国银行')
) and du.id < 3;

        先看看原始SQL后(先心里有一个执行顺序),在配合explain中的序号和别名,看是否一致。 

        中国银行的储蓄用户,第一步:先查询中国银行id。第二部:在查询中国银行id对于的用户id。第三步:根据用户id,查询用户信息。根据步骤可以看出执行顺序:db,dba,du。explain执行顺序:3,2,1。可以看出结论与我们分析的一致,结论成立。

2.3.1.2、select_type

        select_type:搜索类型,常见类型 SIMPLE、PRIMARY、SUBQUERY、DERIVED、UNION等。

具体主要类型分析:

  • Simple(简单类型)
    • 简单的 SELECT 查询,不包含子查询或 UNION
  • PRIMARY(最外层查询)
    • 最外层查询,如果查询中包含任何复杂的子部分,最外层查询则被标记为 PRIMARY
  • SUBQUERY(子查询)
    • 在 SELECT 或 WHERE 列表中包含了子查询。
  • DERIVED
    • 在 FROM 列表中包含的子查询被标记为 DERIVED(衍生),MySQL 会递归执行这些子查询,把结果放在临时表里。
    • 后续补充
  • UNION
    • 如果第二个 SELECT 出现在 UNION 之后,则被标记为 UNION;若 UNION 包含在 FROM 子句的子查询中,外层 SELECT 将被标记为 DERIVED
    • 后续补充
  • UNION RESULT
    • 从 UNION 表获取结果的 SELECT
    • 后续补充
  • DEPENDENT SUBQUERY
    • 在 SELECT 或 WHERE 列表中包含了子查询,子查询基于外层。
    • 后续补充
  • UNCACHEABLE SUBQUERY
    • 无法被缓存的子查询。
    • 后续补充
2.3.1.3、table

        执行SQL所属表。

2.3.1.4、partitions

        匹配的分区信息。如果查询是基于分区表的话,会显示查询将访问的分区

2.3.1.5、type(类型)

        访问类型,如 ALL(全表扫描)、index(全索引扫描)、range(范围扫描)、ref(非唯一索引扫描)、eq_ref(唯一索引扫描),const(常量),system(系统) 等。

        性能从大到小  const > eq_ref > ref > range > index > all。如果Sql类型是 ALL 就必须优化,index 尽可能优化到range。

2.3.1.6、possible_keys

        SQL可能使用的索引,包含零个或多个。

2.3.1.7、key

        SQL使用的索引。

2.3.1.8、key_len

        SQL只用的索引长度。

2.3.1.9、ref

        显示索引的哪一列被使用了,如果可能的话,是一个常数,哪些列或常量被用于查找索引列上的值。

2.3.1.10、rows

        SQL执行影响行数,不是很准确。

2.3.1.11、filtered

        查询的表行占表的百分比。

2.3.1.12、extra

        拓展信息,也是SQL分析最重要的列。

3、常见SQL问题

3.1、未走索引,全表检索

        explain 中 type 显示 ALL 时 是没有走到索引的,具体可查看 key 列。

3.2、分组未走索引

        group by 中的字段没有建立索引,造成extra列显示 Using temporary 信息。

3.2、排序未走索引

        order by 中字段没有走索引。extra列显示 Using filesort 信息

3.3、索引失效

        字段建立索引没有走到。type 值显示 ALL

4、优化策略

4.0、数据结构

CREATE TABLE `d_user` (`id` int NOT NULL COMMENT '主键id',`user_id` varchar(50) NOT NULL COMMENT '用户id',`user_name` varchar(100) NOT NULL COMMENT '用户名',`phone` varchar(100) NOT NULL,`age` int NOT NULL,`gender` tinyint DEFAULT '0' COMMENT '性别',`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`test_not_null` varchar(10) DEFAULT NULL,PRIMARY KEY (`id`),UNIQUE KEY `idx_user_qe_user_id` (`user_id`),KEY `idx_phone` (`phone`)
) ENGINE=InnoDB COMMENT='用户信息表';CREATE TABLE `d_bank` (`id` int NOT NULL COMMENT '主键id',`bank_id` varchar(50) NOT NULL COMMENT '银行id',`bank_name` varchar(50) NOT NULL COMMENT '银行名',`address` varchar(255) DEFAULT NULL COMMENT '地址',`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='银行表';CREATE TABLE `d_bank_account` (`id` int NOT NULL AUTO_INCREMENT COMMENT '主键id',`account_id` varchar(50) NOT NULL COMMENT '银行卡id',`account_no` varchar(50) NOT NULL COMMENT '银行卡编号',`account_type` tinyint DEFAULT '0' COMMENT '银行卡类型',`bank_id` varchar(50) DEFAULT NULL COMMENT '银行卡id',`user_id` varchar(50) DEFAULT NULL COMMENT '持有人',`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',PRIMARY KEY (`id`)
) ENGINE=InnoDB comment='用户储蓄账号关系表';

4.1、策略方向

        1、经常搜索列建立索引。2、最左前缀匹配法则。3、索引覆盖。

        我们回顾哈上篇文章的索引:主键索引、唯一索引、普通索引(单列索引、联合索引)、全文索引(一般不用)

        建议:尽可能新建联合索引,少新建单列索引,能走主键索引绝不走唯一索引或普通索引(避免回表查询)。

4.2、问题分析

4.2.0、前序信息

表信息索引信息索引截图数据量
d_user999803
d_bank5
d_bank_account2774925

查看索引语法:

## 查询表索引
## table_name 数据表
show index from table_name;

4.2.1、未走索引现象与优化

案例一:查询手机号='13500000215'用户信息

语句:select * from d_user where phone = '13500000215';

数据:可以看出执行耗时1.5秒

 explain分析:可以看出 type = ALL 且 key = null 没有走索引。

对phone字段添加索引: 

        图中可知:type 由 all 优化为了 ref , key 也使用了刚刚新建索引,整个耗时由 1.5秒提升至 忽略不计。

案例二:查询user_id=4a163cc6e18341698bc9b3a8ce64ee88用户信息

        图中可知:耗时1.5秒左右。

        分析:用户id在整个系统中应该唯一,不可能出现所谓了重复问题,所以对user_id字段添加唯一索引。

 总结:通过上面两个案例可知,走索引与不走索引的性能差异之大,其中唯一索引性能提升最大,type 等于了 const,这也是 SQL优化中 最优解,但是这个类型只有唯一索引与主键索引可以达到,其他的索引最多只能达到eq_ref ,索引优化中常见是 ref 是最优。

4.2.2、走索引缺失效与优化

        索引失效常见有如下几种场景:

4.2.2.1、未走 最左前缀匹配法则,导致索引失效。

        可以看出 age 字段在联合索引中,但是

4.2.2.2、范围查询列之后列,不走索引。
4.2.2.2.1、案例分析

        是否失效需要查看联合索引中各个字段的索引长度:

        a)先看看全匹配联合索引的索引长度:key_len = 408

        b) 查看gender索引长度:408 - 106 = 2

        c)查看age与user_name索引长度:age :408 - 402 = 6。user_name : 402

         从上面三个步骤来看三个字段索引长度,usename = 402, age = 6, gender = 2

 案例一:查看姓名=‘测试用户2’ 且 年龄>20 且 性别=1;

         图中可知:索引长度 = 406 缺少了 gender的索引长度(失效)。

        解决方式:范围查询 更改 范围查询+等值查询。例如: > 更改 >= , < 更改 <=等。

 下图可知:将 > 更改为 >= 后,走全索引。

4.2.2.2.2、结论

         范围查询 需要将 > ,< 更换为 >=, <=来走索引。

4.2.2.3、全模糊或前缀模糊不走索引。
4.2.2.3.1、案例分析

案例一:查询姓名包含测试用户的储蓄用户。

案例二:查询已123结尾的储蓄用户。

4.2.2.3.2、结论

        从上面两个案例来看,对于字符类型的模糊匹配会造成索引失效(不走索引)。

解决方式:采用后缀匹配 即 like 'xxx%';

        图中可知:后缀模糊匹配与等值匹配都走索引,且索引长度一致,除type不一致外。

4.2.2.4、函数计算索引失效。
4.2.2.4.1、案例分析

案例一:查询用户姓名长度大于7的信息

案例二:查询以前2个字符为前缀匹配

4.2.2.4.2、结论

        从上面两个案例来看,对于使用计算函数列无法采用索引。

解决方式:1、创建函数索引(8.0引入)。2、索引覆盖

4.2.2.5、or条件索引失效
4.2.2.5.1、案例分析

案例一:前面条件走索引字段 or 条件字段不是索引字段

案例二:前面条件走索引 or 条件字段索引失效 

4.2.2.5.2、结论

        从上面两个案例可知:一旦 or中某一条件索引失效,整个SQL的索引都失效。

解决方法:or 前后条件都走索引。

5、总结

        本文还未完善,后续会补充 多表关联讲解。

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

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

相关文章

修改成清华镜像源解决Anaconda报The channel is not accessible源通道不可用问题

修改成清华镜像源解决Anaconda报The channel is not accessible源通道不可用问题 最近在通过pycharm开发python程序&#xff0c;引用anaconda环境建立虚拟环境时报错&#xff0c;报UnavailableInvalidChannel: The channel is not accessible or is invalid.应该是镜像源访问通…

Selenium+Java(21):Jenkins发送邮件报错Not sent to the following valid addresses解决方案

问题现象 小月妹妹近期在做RobotFrameWork自动化测试,并且使用Jenkins发送测试邮件的时候,发现报错Not sent to the following valid addresses,明明各个配置项看起来都没有问题,但是一到邮件发送环节,就是发送不出去,而且还不提示太多有用的信息,急的妹妹脸都红了,于…

Redis6为什么引入了多线程?

大家好&#xff0c;我是锋哥。今天分享关于【Redis6为什么引入了多线程&#xff1f;】面试题。希望对大家有帮助&#xff1b; Redis6为什么引入了多线程&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Redis 6 引入了多线程的主要目的是提高性能&#…

【模块一】kubernetes容器编排进阶实战之kubernetes 资源限制

kubernetes 资源限制 kubernetes中资源限制概括 1.如果运行的容器没有定义资源(memory、CPU)等限制&#xff0c;但是在namespace定义了LimitRange限制&#xff0c;那么该容器会继承LimitRange中的 默认限制。 2.如果namespace没有定义LimitRange限制&#xff0c;那么该容器可…

Rancher V2.9.0 Docker安装教程

1、创建Rancher挂载目录 mkdir -p /home/rancher/k3s/agent/images/ 2、复制容器中的镜像tar包&#xff0c;防止挂载之后镜像包丢失导致创建集群报错 避免&#xff1a;Internal error occurred: failed calling webhook "default.cluster.cluster.x-k8s.io" dock…

CPT203 Software Engineering 软件工程 Pt.1 概论和软件过程(中英双语)

文章目录 1.Introduction1.1 What software engineering is and why it is important&#xff08;什么是软件工程&#xff0c;为什么它很重要&#xff09;1.1 We can’t run the modern world without software&#xff08;我们的世界离不开软件&#xff09;1.1.1 What is Soft…

从 Coding (Jenkinsfile) 到 Docker:全流程自动化部署 Spring Boot 实战指南(简化篇)

前言 本文记录使用 Coding (以 Jenkinsfile 为核心) 和 Docker 部署 Springboot 项目的过程&#xff0c;分享设置细节和一些注意问题。 1. 配置服务器环境 在实施此过程前&#xff0c;确保服务器已配置好 Docker、MySQL 和 Redis&#xff0c;可参考下列链接进行操作&#xff1…

[WASAPI]音频API:从Qt MultipleMedia走到WASAPI,相似与不同

[WASAPI] 从Qt MultipleMedia 来看WASAPI 最近在学习有关Windows上的音频驱动相关的知识&#xff0c;在正式开始说WASAPI之前&#xff0c;我想先说一说Qt的Multiple Media&#xff0c;为什么呢&#xff1f;因为Qt的MultipleMedia实际上是WASAPI的一层封装&#xff0c;它在是线…

绝美的数据处理图-三坐标轴-散点图-堆叠图-数据可视化图

clc clear close all %% 读取数据 load(MyColor.mat) %读取颜色包for iloop 1:25 %提取工作表数据data0(iloop) {readtable(data.xlsx,sheet,iloop)}; end%% 解析数据 countzeros(23,14); for iloop 1:25index(iloop) { cell2mat(table2array(data0{1,iloop}(1,1)))};data(i…

第三百四十六节 JavaFX教程 - JavaFX绑定

JavaFX教程 - JavaFX绑定 JavaFX绑定同步两个值&#xff1a;当因变量更改时&#xff0c;其他变量更改。 要将属性绑定到另一个属性&#xff0c;请调用bind()方法&#xff0c;该方法在一个方向绑定值。例如&#xff0c;当属性A绑定到属性B时&#xff0c;属性B的更改将更新属性A…

详解VHDL如何编写Testbench

1.概述 仿真测试平台文件(Testbench)是可以用来验证所设计的硬件模型正确性的 VHDL模型&#xff0c;它为所测试的元件提供了激励信号&#xff0c;可以以波形的方式显示仿真结果或把测试结果存储到文件中。这里所说的激励信号可以直接集成在测试平台文件中&#xff0c;也可以从…

RNA-Seq 数据集、比对和标准化

RNA-Seq 数据集、比对和标准化|玉米中的元基因调控网络突出了功能上相关的调控相互作用。 RNA-Seq 表达分析代码和数据 该仓库是一个公开可用 RNA-Seq 数据集的集合&#xff08;主要是玉米数据&#xff09;&#xff0c;提供了系统分析这些数据的代码/流程&#xff0c;以及质量…

学技术学英文:Spring AOP和 AspectJ 的关系

AspectJ是AOP领域的江湖一哥&#xff0c; Spring AOP 只是一个小弟 Spring AOP is implemented in pure Java. There is no need for a special compilation process. Spring AOP does not need to control the class loader hierarchy and is thus suitable for use in a ser…

JVM学习-内存结构(二)

一、堆 1.定义 2.堆内存溢出问题 1.演示 -Xmx设置堆大小 3.堆内存的诊断 3.1介绍 1&#xff0c;2都是命令行工具&#xff08;可直接在ideal运行时&#xff0c;在底下打开终端&#xff0c;输入命令&#xff09; 1可以拿到Java进程的进程ID&#xff0c;2 jmap只能查询某一个时…

Browser Use:AI智能体自动化操作浏览器的开源工具

Browser Use:AI智能体自动化操作浏览器的开源工具 Browser Use 简介1. 安装所需依赖2. 生成openai密钥3. 编写代码4. 运行代码5. 部署与优化5.1 部署AI代理5.2 优化与扩展总结Browser Use 简介 browser-use是一个Python库,它能够帮助我们将AI代理与浏览器自动化操作结合起来;…

Spring Cloud——注册中心

介绍 什么是注册中心&#xff1f; 主要负责服务的注册与发现&#xff0c;确保服务之间的通信顺畅&#xff0c;具体来说&#xff0c;注册中心有以下主要功能&#xff1a;‌服务注册、服务发现、服务健康检查。 服务注册&#xff1a; 服务提供者在启动时会向注册中心注册自身服务…

CSS基础入门【2】

目录 一、知识复习 二、权重问题深入 2.1 同一个标签&#xff0c;携带了多个类名&#xff0c;有冲突&#xff1a; 2.2 !important标记 2.3 权重计算的总结 三、盒模型 3.1 盒子中的区域 3.2 认识width、height 3.3 认识padding 3.4 border 作业&#xff1a; 一、知识…

捋一捋相关性运算,以及DTD和NLP中的应用

捋一捋相关性运算&#xff0c;以及DTD和NLP中的应用 相关性和相干性,有木有傻傻分不清相关性数字信号的相关运算同维度信号的相关理解 相关--互相关--相干 回声消除过程如何套用这些知识相关性/相干性检测在DT中的应用时域的标量与向量结合的互相关方法适合block处理的频域相干…

Elasticsearch:normalizer

一、概述 ‌Elastic normalizer‌是Elasticsearch中用于处理keyword类型字段的一种工具&#xff0c;主要用于对字段进行规范化处理&#xff0c;确保在索引和查询时保持一致性。 Normalizer与analyzer类似&#xff0c;都是对字段进行处理&#xff0c;但normalizer不会对字段进…

go语言的成神之路-筑基篇-对文件的操作

目录 一、对文件的读写 Reader?接口 ?Writer接口 copy接口 bufio的使用 ioutil库? 二、cat命令 三、包 1. 包的声明 2. 导入包 3. 包的可见性 4. 包的初始化 5. 标准库包 6. 第三方包 ?7. 包的组织 8. 包的别名 9. 包的路径 10. 包的版本管理 四、go mo…