【MySQL】SQL调优:数据库性能剖析

前言:本文将简单介绍一下如何实现数据库的性能剖析,以及介绍一下剖析工具的基本使用方法

一,为什么要性能剖析?

你在执行一条SQL语句时,发现服务器响应很慢,执行效率很低。通过EXPLAIN执行语句发现了问题。哦,这是一条慢查询!那么你接下来开始想办法对这条SQL语句进行优化,接下来如何着手?

数据库的优化是在一定的负载下尽可能降低服务器的响应时间

优化的前提条件是测量

优化的难点不在于改,而是以测量的结果作为依据,和需求的数据进行对比。从而发现病灶

确认查询开销是花费在等待上还是执行上

如果一条服务器处理一条请求95%的时间都在等待IO完成,但是执行sql的时间仅占5%,这时候优化sql语句的执行效率就是无意义的。

平均结果无法反映一条sql语句的具体效率

执行慢查询,从服务器整体运行开销来分析问题所在这是不合理的。要对慢查询进行测量而不是只测量服务器整体。

完成一项任务所需的时间可以分为等待时间+执行时间

执行时间受到应用层的影响,比如使用了暴搜或者索引失效

等待时间则会与其他线程之间竞争资源有关

不能执着于单条sql语句的查询

当一个用户进行交互时,其操作往往涉及到多个查询语句,这时候仅关注一条sql的执行效率,就无法把用户交互行为涉及到的查询关联起来,也就是管中窥豹,后续在性能剖析中会介绍如何实现聚合性能分析

二,对应用程序进行剖析

这里介绍一下如何使用Arthas来进行应用层性能剖析

1. 下载Arthas

在 Windows 中打开 PowerShell,进入你想要存放工具的目录(比如 D:\tools),执行以下命令:

PowerShell

复制代码
curl -O https://arthas.aliyun.com/arthas-boot.jar
  • 注意: 如果你的电脑没装 curl,直接通过浏览器访问 Arthas 官网 下载这个 .jar 文件即可。

2. 启动,挂载服务器

启动Arthas之前我们需要先启一个服务,这里以我之前写的TCP回显服务器为例

程序启动之后使用arthas检测对应进程,在控制台输入:

复制代码
java -jar arthas-boot.jar

输入我们想要监测的序号,注意不要输入PID

执行到这一步,再继续对终端进行输入会发现出现输入和粘贴数据缺失的现象发生,这是因为我们在控制台的交互行为会因为网络波动导致输入的字符流丢失。这里我们切换为Web 控制台完成后续流程

复制代码
打开浏览器,输入 http://127.0.0.1:8563/

进入 Web 控制台后,按顺序执行以下三个核心诊断操作,观察 TCP 代码如何运行:

A. 整体扫描:dashboard

输入 dashboard

  • 目的: 看看你的 newCachedThreadPool 是否在疯狂创建线程,或者内存是否有异常。

  • 退出:Ctrl + C

B. 追踪交互链路:trace

这是你之前最想要的。直接粘贴这行命令:

Bash

复制代码
trace netWork.tcpEchoServer processConnection
  • 操作: 回到你的 tcpEchoClient 发送一条消息。

  • 观察点: 网页上会立刻弹出一棵树。你会看到 processConnection 内部如何分步执行:从获取流到调用 process,每一步的耗时(微秒级)清晰可见。

在TCP客户端上输入一条信息,观察控制台响应结果

C. 多次输入

在客户端控制台多次输入,观察结果:

D. 制造延迟

由于 process 方法太快了(7 微秒),快到让性能分析失去了挑战性。你想试试**"定位生产环境瓶颈"**的模拟吗?

  1. 修改服务器代码 :在 process 方法里随机制造一点延迟。

    Java

    复制代码
    public String process(String request) {
        if ("slow".equals(request)) {
            try { Thread.sleep(200); } catch (InterruptedException e) {} 
        }
        return request;
    }

热更新代码(不重启服务器)

如果你刚才是在 IDE 里改了代码并重新编译成了 .class 文件,你可以利用 Arthas 的 retransform 命令让新逻辑直接在运行中的服务器生效:

  1. 加载新类

    Bash

    复制代码
    retransform "C:\你的路径\netWork\tcpEchoServer.class"
  2. 验证 :看到 retransform success 后,你的服务器逻辑就已经原地升级了。

利用 tt 发起"时光倒流"测试

tt 的核心理念是:"记录一次,无限重放"。你不需要反复去客户端敲字,只要抓到一次"样本",就可以在服务端无限次模拟这次请求,验证你的代码逻辑和性能。

共划分为 4 步标准操作:

第一步:开启记录仪(布下陷阱)

首先,告诉 Arthas 你要监控 process 方法。

Bash

复制代码
tt -t netWork.tcpEchoServer process
  • 状态 :此时控制台会显示 Press Q or Ctrl+C to abort.,说明它正在后台静静等待请求到来。

第二步:制造"样本"请求(关键!)

因为 tt 只能重放 已经发生过的请求,所以你需要先去客户端发送一次符合你测试目标的请求。

  • 操作 :去 tcpEchoClient 的黑窗口,输入 slow 并回车。

  • 目的 :因为你的新代码逻辑是 if ("slow".equals(request)) 才会触发延迟。如果你只发送 hello,重放一万次也测不出那 200ms 的延迟。

  • Arthas 的反应 :你会看到控制台立刻弹出一行记录,记下那个 INDEX (比如 1002)。

第三步:发起重放测试(时光倒流)

现在你可以把客户端关了,甚至拔掉网线,我们直接在服务端"重放"刚才那条请求。

刚才记录到的索引是 1001,输入:

Bash

复制代码
tt -i 1001 -p
  • -i 1001:指定要重放的那条记录的索引。

  • -p :Play(重放)。这是最神奇的一步,Arthas 会主动调用一次 process("slow")


第四步:验收结果(看真相)

执行完命令后,你会看到类似下面的输出,请重点看这两个指标:

  1. COST (耗时)

    • 预期 :应该在 200ms 左右

    • 分析 :如果之前的请求是 0.0x ms,而这次重放变成了 200ms,恭喜你!热更新成功了,代码逻辑已生效。

  2. result (返回值)

    • 预期 :显示 @String[slow]

⚔️ 进阶:压力测试(疯狂重放)

如果你想看看这 200ms 的延迟会不会把你的线程池拖垮,可以让 Arthas 疯狂重放这个请求:

Bash

复制代码
# 每隔 100ms 重放一次,总共重放 50 次,也就是持续 5 秒的压力测试
tt -i 1001 -p --replay-times 50 --replay-interval 100

对比先后的时间开销,得出process方法是影响性能的主要罪魁祸首

修改process代码逻辑即可修正。

以上只是对于服务器的串行测试,如果想要正在给服务器施压,可以使用jmeter压测工具

相关推荐
星辰_mya2 小时前
Elasticsearch之中
java·服务器·数据库
UpYoung!2 小时前
【SQL Server 2019】企业级数据库系统—数据库SQL Server 2019保姆级详细图文下载安装完全指南
运维·数据库·sqlserver·运维开发·数据库管理·开发工具·sqlserver2019
fengxin_rou2 小时前
[Redis从零到精通|第三篇]:缓存更新指南
java·数据库·redis·spring·缓存
郝亚军2 小时前
Ubuntu启一个tcp server,client去连接
linux·服务器·数据库
A懿轩A2 小时前
【MySQL 数据库】SQL 基础语法速成:SELECT / INSERT / UPDATE / DELETE 一篇上手增删改查
数据库·sql·mysql
范纹杉想快点毕业2 小时前
状态机设计模式与嵌入式系统开发完整指南
java·开发语言·网络·数据库·mongodb·设计模式·架构
李慕婉学姐2 小时前
Springboot眼镜店管理系统ferchy1l(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·spring boot·后端
小贺儿开发2 小时前
Unity3D 智慧城市管理平台
数据库·人工智能·unity·智慧城市·数据可视化
瀚高PG实验室2 小时前
HighGo Database中的约束条件
数据库·瀚高数据库