当前位置: 首页 > news >正文

MySQL性能调优实战手册:从慢查询到执行计划全解析

一、调优流程四步走 🚀

当我们遇到数据库调优问题的时候,该如何思考呢?
这里把思考的流程整理成下面这张图。
整个流程划分成了观察(Show status)行动(Action)两个部分。字母S的部分代表观察(会使用相应的分析工具),字母A代表的部分是行动(对应分析可以采取的行动)。

  • 周期性波动:双十一/促销活动导致流量激增,需提前扩容
  • 突发性能问题:用 SHOW STATUS 定位瓶颈(如慢查询暴增)
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    小结
    在这里插入图片描述

二、性能监控三板斧 🔍

1️⃣ 系统性能参数速查

--查看sql执行频次,如果查询占比较高,需要进行下一步的优化动作。
SHOW  [GLOBAL|SESSION] STATUS LIKE '参数'

一些常用的性能参数如下:

  • Connections:连接MySQL服务器的次数。
  • Uptime: MySQL服务器的上线时间。
  • Slow_queries:慢查询的次数。
  • lnnodb_rows_read : select查询返回的行数
  • lnnodb_rows_inserted:执行INSERT操作插入的行数
  • lnnodb_rows_updated:执行UPDATE操作更新的行数
  • lnnodb_rows_deleted:执行DELETE操作删除的行数
  • com_select:查询操作的次数。
  • Com_insert:插入操作的次数。对于批量插入的INSERT 操作,只累加一次。
  • Com_update:更新操作的次数。
  • Com_delete:删除操作的次数。

2️⃣ 查询成本分析 last_query_cost

在执行 SQL 查询前,MySQL 确定执行计划并计算其成本,选择成本最低的计划。如果想查看某条 SQL 的查询成本,可以使用以下命令:

SHOW  STATUS LIKE 'last_query_cost'

这个成本通常与 SQL 语句读取的页数相关,是评估查询效率的常用指标。在这里插入图片描述

使用场景

  • 位置决定效率:数据页在数据库缓冲池中时效率最高;若不在,则需从内存或磁盘读取,内存读取显著更快。
    批量决定效率:单页随机读取效率低(约 10ms),而顺序读取多页效率更高,甚至优于内存中的随机读取。
    优化建议
  • 将常用数据放入缓冲池。
  • 利用磁盘的吞吐能力,批量读取数据以提高单页读取效率。

3️⃣ 慢查询日志实战

1. 什么是慢查询日志?

  • 慢查询日志记录运行时间超过 long_query_time 阈值的 SQL 语句。默认情况下,long_query_time 为 10 秒,表示执行超时的 SQL 语句。

2. 主要作用:

  • 慢查询日志帮助识别执行时间长的查询,以便进行优化,提升系统效率。在数据库阻塞或变慢时,检查慢查询日志可以帮助定位问题。

3. 开启慢查询日志:
默认情况下,慢查询日志是关闭的。可以通过以下命令开启:

SHOW VARIABLES LIKE '%slow_query_log';  # 查看当前状态
SET GLOBAL slow_query_log = 'ON';  # 开启慢查询日志

4. 修改long_query_time:
设置阈值以记录更短时间的慢查询:

SET GLOBAL long_query_time = 1;  # 设置为1秒
SHOW GLOBAL VARIABLES LIKE '%long_query_time%';

要永久生效,可以在 /etc/my.cnf 中添加以下配置:

[mysqld]
slow_query_log=ON #开启慢查询日志的开关
slow_query_log_file=/var/lib/mysql/atguigu-slow.log #慢查询日志的目录和文件名信息,如果不指定文件名默认文件名为 hostname-slow.log。
long_query_time=3 #设置慢查询的阈值为3秒,超出此设定值的SQL即被记录到慢查询日志
log_output=FILE
# 如果不指定存储路径,慢查询日志将默认存储到MySQL数据库的数据文件夹下。

5. 查看慢查询记录
查询当前系统的慢查询条数:

SHOW GLOBAL STATUS LIKE '%slow_queries%';

6. 慢查询日志分析工具
使用 mysqldumpslow 命令分析慢查询日志:

mysqldumpslow -s t -t 5 /var/lib/mysql/atguigu05-slow.log  # 查看前5条

示例:
在这里插入图片描述

7. 关闭慢查询日志

  • 永久性关闭:修改配置文件,将 slow_query_log 设置为 OFF,然后重启 MySQL。
[mysqld]
slow_query_log=OFF  # 注释也可

- 临时关闭:

set global slow_query_log='OFF' 
  1. 删除慢查询日志
    手动删除慢查询日志文件,或使用以下命令重新生成日志:
mysqladmin -uroot -p flush-logs slow

注意:慢查询日志的目录(/var/lib/mysql/xx.log)默认为MySQL的数据目录,执行此命令后,旧日志将被替换,建议提前备份。

三:SQL解剖刀:EXPLAIN执行计划 🔧

在定位慢查询后,可以使用 EXPLAINDESCRIBE 工具分析 SQL 语句的执行计划。EXPLAIN 展示查询的执行方式,包括多表连接顺序及访问方法。

1. 能做什么?

  • 表的读取顺序
  • 数据读取操作类型
  • 可用的索引
  • 实际使用的索引
  • 表之间的引用
  • 每张表优化后的行数

2. 官网介绍
https://dev.mysql.com/doc/refman/5.7/en/explain-output.html
https://dev.mysql.com/doc/refman/8.0/en/explain-output.html

3. 版本情况

  • 查看某个查询的执行计划,可以在具体的查询语句前加一个 EXPLAIN
  • MySQL 5.6.3 之前只能对 SELECT 使用 EXPLAIN;之后支持对 UPDATE 和 DELETE。
  • 在5.7以前的版本中,想要显示partitions需要使用explain partitions 命令;想要显示filtered需要使用explain extended命令。在5.7版本后,默认explain直接显示partitions和filtered中的信息
    tip: 执行EXPLAIN时并没有真正的执行该后面的语句,因此可以安全的查看执行计划.

基本语法

EXPLAIN/DESCRIBE select/delete/update/insert ... ...

4. EXPLAIN各列作用

1. table 表名

查询的每一行记录对应一个表。

#s1: 驱动表  s2: 被驱动表
EXPLAIN SELECT * FROM s1 INNER JOIN s2;

tip: 表名可以是别名或临时表。

2. id 查询标识,标识执行顺序

标识执行顺序。

  • 相同的 id 值表示同组查询,按照从上到下的顺序执行。
  • 在同一组中,id值越大,优先级越高,越先执行
  • 关注点: id号每个号码,表示一趟独立的查询,一个sql的查询趟数越少越好
    在这里插入图片描述在这里插入图片描述在这里插入图片描述

3. select_type 查询类型

  • SIMPLE:简单查询,无 UNION 或子查询。
  • PRIMARY:最外层查询。
  • UNION:后续的 UNION 查询。
  • SUBQUERY:子查询。
  • DEPENDENT UNION:依赖外部查询的 UNION。
  • DERIVED:派生表查询。
#查询语句中不包含`UNION`或者子查询的查询都算作是`SIMPLE`类型EXPLAIN SELECT * FROM s1;
#连接查询也算是`SIMPLE`类型EXPLAIN SELECT * FROM s1 INNER JOIN s2;#对于包含`UNION`或者`UNION ALL`或者子查询的大查询来说,它是由几个小查询组成的,其中最左边的那个查询的`select_type`值就是`PRIMARY`,其中除了最左边的那个小查询以外,其余的小查询的`select_type`值就是`UNION`#`MySQL`选择使用临时表来完成`UNION`查询的去重工作,针对该临时表的查询的`select_type`就是
`UNION RESULT`EXPLAIN SELECT * FROM s1 UNION SELECT * FROM s2;#子查询:如果包含子查询的查询语句不能够转为对应的`semi-join`的形式,并且该子查询是不相关子查询, 则该子查询的第一个`SELECT`关键字代表的那个查询的`select_type`就是`SUBQUERY`EXPLAIN SELECT * FROM s1 WHERE key1 IN (SELECT key1 FROM s2) OR key3 = 'a';# 如果包含子查询的查询语句不能够转为对应的`semi-join`的形式,并且该子查询是相关子查询,则该子查询的第一个`SELECT`关键字代表的那个查询的`select_type`就是`DEPENDENT SUBQUERY`EXPLAIN SELECT * FROM s1 WHERE key1 IN (SELECT key1 FROM s2 WHERE s1.key2 = s2.key2) OR key3 = 'a';注意的是,select_type为`DEPENDENT SUBQUERY`的查询可能会被执行多次。#在包含`UNION`或者`UNION ALL`的大查询中,如果各个小查询都依赖于外层查询的话,那除了最左边的那个小查询之外,其余的小查询的`select_type`的值就是`DEPENDENT UNION`。EXPLAIN SELECT * FROM s1 WHERE key1 IN (SELECT key1 FROM s2 WHERE key1 = 'a' UNION SELECT key1 FROM s1 WHERE key1 = 'b');#对于包含`派生表`的查询,该派生表对应的子查询的`select_type`就是`DERIVED`EXPLAIN SELECT * FROM (SELECT key1, COUNT(*) AS c FROM s1 GROUP BY key1) AS derived_s1 WHERE c > 1;#当查询优化器在执行包含子查询的语句时,选择将子查询物化之后与外层查询进行连接查询时,#该子查询对应的`select_type`属性就是`MATERIALIZED`EXPLAIN SELECT * FROM s1 WHERE key1 IN (SELECT key1 FROM s2); #子查询被转为了物化表

4. partitions(可略)

匹配的分区信息

5. type(比较重要)

单表的访问方法,表示查询效率。

  • system:只有一条记录的系统表。
  • const:最多一条匹配记录,速度非常快。
  • eq_ref:每个组合的行读取,最佳类型。
  • ref:读取匹配索引值的所有行。
  • fulltext:使用 FULLTEXT 索引。
  • index_merge:使用索引合并。
  • ALL:全表扫描,通常效率最低。
    PS:越靠前越好
#当表中`只有一条记录`并且该表使用的存储引擎的统计数据是`精确`的,比如 MyISAM、Memory
特点:数据量较少,往往不需要磁盘IO,速度非常快
那么对该表的访问方法就是`system`。CREATE TABLE t(i INT) ENGINE=MYISAM;INSERT INTO t VALUES(1);EXPLAIN SELECT * FROM t;当我们根据`主键`或者`唯一二级索引列``常数`进行等值匹配时,对单表的访问方法就是`const`特点:扫描效率较高,返回数据量少,速度非常快EXPLAIN SELECT * FROM s1 WHERE id = 10005;# 在连接查询时,如果`被驱动表`是通过`主键`或者`唯一二级索引列``等值匹配`的方式进行访问的(如果该主键或者唯一二级索引是联合索引的话,所有的索引列都必须进行等值比较),则对该被驱动表的访问方法就是`eq_ref`EXPLAIN SELECT * FROM student_info s INNER JOIN course c ON s.course_id = c.id;tip:id为course表的主键# 当通过普通的`二级索引列`与`常量`进行等值匹配时来查询某个表,那么对该表的访问方法就可能是`ref`特点:使用非唯一性索引,会找到多个符合条件的行EXPLAIN SELECT * FROM s1 WHERE key1 = 'a';# 当对`普通二级索引`进行`等值`匹配查询,该索引列的值也可以是`NULL`值时,那么对该表的访问方法就可能是`ref_or_null`EXPLAIN SELECT * FROM s1 WHERE key1 = 'a' OR key1 IS NULL;#  单表访问方法时在某些场景下可以使用`Intersection`、`Union`、
`Sort-Union`这三种索引合并的方式来执行查询,访问方式就是 `index_merge`(此时key1和keys都是索引)EXPLAIN SELECT * FROM s1 WHERE key1 = 'a' OR key3 = 'a';# unique_subquery`是针对在一些包含`IN`子查询的查询语句中,如果查询优化器决定将`IN`子查询转换为`EXISTS`子查询, 而且子查询可以使用到主键进行等值匹配的话,那么该子查询执行计划的`type`列的值就是`unique_subquery`EXPLAIN SELECT * FROM s1 WHERE key2 IN (SELECT id FROM s2 WHERE s1.key1 = s2.key1) OR key3 = 'a';//value IN (SELECT primary_key FROM single_table WHERE some_expr)# 如果使用`索引`获取某些`范围区间`的记录,那么就可能使用到`range`访问方法特点:使用`索引字段`在where语句中使用 bettween...and、<><=、in 等范围条件查询 type 都是 range。EXPLAIN SELECT * FROM s1 WHERE key1 IN ('a', 'b', 'c');#同上EXPLAIN SELECT * FROM s1 WHERE key1 > 'a' AND key1 < 'b';#当我们可以使用`索引覆盖`,但需要扫描全部的索引记录时,该表的访问方法就是`index`,遍历索引树读取。如下表(key_pat1, key_part2, key_part3)为联合索引,不用走全表扫描可完成查询EXPLAIN SELECT key_part2 FROM s1 where key_part3 = 'a';#最熟悉的全表扫描`ALL`,从磁盘中读取EXPLAIN SELECT * FROM s1;

小结:

  • 结果值从最好到最坏依次是:
    system > const > eq_ref > ref fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
  • SQL性能优化的目标:至少要达到range级别,要求是ref级别,最好是const级别。(阿里巴巴开发手册要求)

6. possible_keys 和 key

  • possible_keys:可能使用的索引,但不一定被查询使用。
  • key 列表示实际用到的索引有哪些,如果为NULL,则没有使用索引。

7.key_len

实际使用到的索引长度(单位:字节数),帮你检查,是否充分的利用上了索引,值越大越好(主要针对联合索引,有一定的参考意义)
tip:key_len只计算where条件中用到的索引长度

8.ref

当使用索引列等值查询时,与索引列进行等值匹配的对象信息,常见值有 const、func、null

  • 当使用常量等值查询,显示const
  • 当关联查询,显示相应关联表的关联字段
  • 当查询条件使用了表达式、函数,或者条件列发生内部隐式转换,可能显示为func

9.rows

估计需要读取的行数,值越小越好。

10. filtered

经过搜索条件过滤后的记录百分比,值越高越好

#如果使用的是索引执行的`单表`扫描,那么计算时需要估计出满足除使用到 对应索引的搜索条件外的其他搜索条件的记录有多少条。
EXPLAIN SELECT * FROM s1 WHERE key1 > 'z' AND common_field = 'a';#对于单表查询来说,这个filtered列的值没什么意义,我们更关注在连接查询中驱动表对应的执行计划记录的filtered值,它决定了被驱动表要执行的次数(即:rows * filtered)EXPLAIN SELECT * FROM s1 INNER JOIN s2 ON s1.key1 = s2.key1 WHERE s1.common_field = 'a';

11. extra

额外信息,帮助理解查询执行情况。

 `No table Used`
#当查询语句的没有`FROM`子句时将会提示该额外信息 `No table Used`EXPLAIN SELECT 1;`Impossible WHERE`#查询语句的`WHERE`子句永远为`FALSE`时将会提示该额外信息 `Impossible WHERE`EXPLAIN SELECT * FROM s1 WHERE 1 != 1;`Using where`#1. 当我们使用`全表扫描`来执行对某个表的查询,并且该语句的`WHERE`子句中有针对该表的搜索条件时,在`Extra`列中会提示上述额外信息。`Using where`EXPLAIN SELECT * FROM s1 WHERE common_field = 'a';#2.当使用`索引`访问来执行对某个表的查询,并且该语句的`WHERE`子句中有除了该索引包含的列之外的其他搜索条件时,在`Extra`列中也会提示上述额外信息。`Using where`(key1为主键))EXPLAIN SELECT * FROM s1 WHERE key1 = 'a' AND common_field = 'a';#当查询列表处有`MIN`或者`MAX`聚合函数,但是并没有符合`WHERE`子句中的搜索条件的记录时,将会提示该额外信息 `No matching min/max row`EXPLAIN SELECT MIN(key1) FROM s1 WHERE key1 = 'abcdefg';#有记录时,提示 `Select table optimized away`EXPLAIN SELECT MIN(key1) FROM s1 WHERE key1 = 'NlPros'; # NlPros 是 s1表中key1字段真实存在的数据select * from s1 limit 10;`Using index`#当我们的查询列表以及搜索条件中只包含属于某个索引的列,也就是在可以使用`覆盖索引`的情况下,在`Extra`列将会提示该额外信息。比方说下边这个查询中只需要用到`idx_key1`而不需要回表操作, 提示`Using index`EXPLAIN SELECT idx_key1 FROM s1 WHERE key1 = 'a';#有些搜索条件中虽然出现了索引列,但却不能使用到索引#看课件理解`索引条件下推`,提示`Using index condition`EXPLAIN SELECT * FROM s1 WHERE key1 > 'z' AND key1 LIKE '%a';#在连接查询执行过程中,当被驱动表不能有效的利用索引加快访问速度,MySQL一般会为其分配一块名叫`join buffer`的内存块来加快查询速度,也就是我们所讲的`基于块的嵌套循环算法`,提示`Using where; Using join buffer(hash join)`EXPLAIN SELECT * FROM s1 INNER JOIN s2 ON s1.common_field = s2.common_field;#当我们使用左(外)连接时,如果`WHERE`子句中包含要求被驱动表的某个列等于`NULL`值的搜索条件, 而且那个列又是不允许存储`NULL`值的,那么在该表的执行计划的Extra列就会提示`Not exists`额外信息EXPLAIN SELECT * FROM s1 LEFT JOIN s2 ON s1.key1 = s2.key1 WHERE s2.id IS NULL;#如果执行计划的`Extra`列出现了`Using intersect(...)`提示,说明准备使用`Intersect`索引#合并的方式执行查询,括号中的`...`表示需要进行索引合并的索引名称;#如果出现了`Using union(...)`提示,说明准备使用`Union`索引合并的方式执行查询;#出现了`Using sort_union(...)`提示,说明准备使用`Sort-Union`索引合并的方式执行查询。EXPLAIN SELECT * FROM s1 WHERE key1 = 'a' OR key3 = 'a';(其中key1和keys都是单独的索引)#当我们的`LIMIT`子句的参数为`0`时,表示压根儿不打算从表中读出任何记录,将会提示该额外信息`Zero limit`EXPLAIN SELECT * FROM s1 LIMIT 0;`Using filesort` 
# 若排序操作无法使用到索引,只能在内存中(记录较少的时候)或者磁盘中(记录较多的时候)进行排序,MySQL把这种在内存中或者磁盘上进行排序的方式统称为`文件排序`(英文名:`filesort`)。也就是order by的字段没有索引EXPLAIN SELECT * FROM s1 ORDER BY common_field LIMIT 10;`Using temporary`#在许多查询的执行过程中,MySQL可能会借助`临时表`来完成一些功能,比如去重、排序之类的,比如我们在执行许多包含`DISTINCT`、`GROUP BY`、`UNION`等子句的查询过程中,如果不能有效利用索引来完成
查询,MySQL很有可能寻求通过建立内部的临时表来执行查询。如果查询中使用到了内部的临时表,在执行计划的`Extra`列将会显示`Using temporary`提示EXPLAIN SELECT DISTINCT common_field FROM s1;`Using temporary`EXPLAIN SELECT DISTINCT key1 FROM s1;`Using index`EXPLAIN SELECT common_field, COUNT(*) AS amount FROM s1 GROUP BY common_field;# 执行计划中出现`Using temporary`并不是一个好的征兆,因为建立与维护`临时表`要付出很大成本的,所以我们`最好能使用索引来替代掉使用临时表`。比如:扫描指定的索引idx_key1即可EXPLAIN SELECT key1, COUNT(*) AS amount FROM s1 GROUP BY key1;

小结

  • EXPLAIN不考虑各种cache
  • EXPLAIN不能显示MySQL在执行查询时所作的优化工作
  • EXPLAIN不会告诉你关于触发器、存储过程的信息或用户自定义函数对查询的影响情况
  • 部分统计信息是估算的,并非精确值

5.EXPLAIN的进一步使用

EXPLAIN四种输出格式

EXPLAIN 可以输出四种格式:传统格式、JSON 格式、TREE 格式和可视化输出。用户可以根据需求选择适合的格式。

  1. 传统格式:默认的表格形式。
    在这里插入图片描述

  2. JSON 格式:提供最详尽的信息,包括执行成本。使用方法是在 EXPLAIN 和查询语句之间添加 FORMAT=JSON。

#json格式的explain
EXPLAIN FORMAT=JSON SELECT * FROM s1 INNER JOIN s2 ON s1.key1 = s2.key2 
WHERE s1.common_field = 'a';

在这里插入图片描述

3. TREE格式
自 8.0.16 版本引入,描述查询部分之间的关系执行顺序

EXPLAIN FORMAT=tree SELECT * FROM s1 INNER JOIN s2 ON s1.key1 = s2.key2 WHEREs1 .common_field = 'a ' \G

SHOW WARNINGS的使用

SHOW WARNINGS 可查看与查询执行计划相关的扩展信息。

show warnings \g

例如,如果原本的左连接因条件 s2.common_field IS NOT NULL 被优化为内连接,SHOW WARNINGS 的 Message 字段会反映这一变化。注意,Message 字段展示的信息并不是标准查询语句,而是帮助理解 MySQL 执行查询的参考信息。

四、高级诊断工具 🛠️

1️⃣ 查看SQL执行成本 : SHOW PROFILE

分析当前会话中SQL都做了什么、执行的资源消耗情况的工具,可用于sql调优的测量。默认情况下是关闭状态。

启用和查看
1. 检查状态:

show variables like 'profiling' #查看状态 默认OFF

2. 开启Profiiling

set profiling = 'ON' # 开启show profile

3. 查看执行情况:

SHOW PROFILES;  -- 查看所有执行的 SQL
SHOW PROFILE CPU, BLOCK IO FOR QUERY 12;  -- 查看特定 SQL 的详细信息

示例:
在这里插入图片描述
在这里插入图片描述

常用查询参数:

  • ALL: 显示所有的开销信息。
  • BLOCK IO: 显示块IO开销。
  • CONTEXT SWITCHES: 上下文切换开销。
  • CPU: 显示CPU开销信息。
  • IPC: 显示发送和接收开销信息。
  • MEMORY: 显示内存开销信息。
  • PAGE FAULTS: 显示页面错误开销信息。
  • SOURCE: 显示和Source_function,Source_file,Source_line相关的开销信息。
  • SWAPS: 显示交换次数开销信息。

日常开发注意事项:

  • converting HEAP to MyISA:查询结果过大时,数据会被写入磁盘。
  • Creating tmp table: 创建临时表。数据先拷贝到临时表,用完后再删除。
  • copying to tmp table on disk: 内存中临时表复制到磁盘可能影响性能。
  • locked:锁定问题,监测 SQL 执行中的锁定情况。。

注意
SHOW PROFILE 将被弃用,建议使用 information_schema 中的 profiling 数据表进行查看。

2️⃣. 分析优化器执行计划: OPTIMIZER_TRACE

OPTIMIZER_TRACE 是 MySQL 5.6 引入的功能,用于跟踪优化器的决策(如访问表的方法、开销计算等),并将结果记录到 INFORMATION_SCHEMA.OPTIMIZER_TRACE 表中。此功能默认关闭。
开启trace
要开启 TRACE 并设置格式为 JSON,同时限制最大内存使用:

SET optimizer_trace="enabled=on", end_markers_in_json=on;
set optimizer_trace_max_mem_size=1000000;

开启后,可分析如下语句:

  • SELECT
  • INSERT
  • REPLACE
  • UPDATE
  • DELETE
  • EXPLAIN
  • SET
  • DECLARE
  • CASE
  • IF
  • RETURN
  • CALL

示例
执行查询后,可以通过以下语句查看执行计划:

SELECT * FROM student WHERE id < 10;
SELECT * FROM INFORMATION_SCHEMA.optimizer_trace\G;

3️⃣ MySQL监控分析视图 - sys schema监控

MySQL 5.7.7 引入了 SYS schema,用于简化从 performance_schema 和 information_schema 中获取性能监控数据的复杂性,方便 DBA 快速定位问题。

  1. 主机相关:以 host_summary 开头,汇总 IO 延迟信息。
  2. InnoDB 相关:以 innodb 开头,汇总 InnoDB 缓冲区和事务锁等待信息。
示例:SELECT * FROM sys.innodb_lock_waits;
  1. I/O 相关:以 io 开头,汇总等待 I/O 和 I/O 使用情况。
示例:SELECT file, avg_read, avg_write FROM sys.io_global_by_file_by_bytes ORDER BY avg_read LIMIT 10;
  1. 内存使用情况:以 memory 开头,展示内存使用情况。
  2. 连接与会话信息:汇总会话相关信息。
  3. 表相关:以 schema_table 开头,展示表的统计信息。
示例:SELECT table_schema, table_name, SUM(io_read_requests + io_write_requests) FROM sys.schema_table_statistics GROUP BY table_schema, table_name ORDER BY io DESC;
  1. 索引信息:统计索引使用情况,包括冗余和未使用的索引。
示例:SELECT * FROM sys.schema_redundant_indexes;
  1. 语句相关:以 statement 开头,包含执行全表扫描、使用临时表等信息。
示例:SELECT db, exec_count, query FROM sys.statement_analysis ORDER BY exec_count DESC;
  1. 用户相关:以 user 开头,统计用户的文件 I/O 和执行语句信息。
    风险提示
    查询 SYS schema 可能消耗大量资源,严重时可能导致业务请求阻塞。建议在生产环境中避免频繁查询 SYS、performance_schema 或 information_schema。

五、调优口诀 📜

“一慢二看三分析,执行计划是核心;索引覆盖是王道,小表驱动效率高;监控日志常态化,锁表阻塞早排查”

相关文章:

MySQL性能调优实战手册:从慢查询到执行计划全解析

一、调优流程四步走 &#x1f680; 当我们遇到数据库调优问题的时候&#xff0c;该如何思考呢? 这里把思考的流程整理成下面这张图。 整个流程划分成了观察&#xff08;Show status&#xff09;和 行动(Action&#xff09;两个部分。字母S的部分代表观察&#xff08;会使用相…...

作为高数小白,我尝试理解概念:高数 - 导数

作为C#开发者&#xff0c;其实我是一个高数小白&#xff0c;可是我对它极其好奇&#xff0c;非常想了解它里面到底讲了什么内容&#xff0c;貌似这对于我是一个非常艰难的过程&#xff0c;因为完全没有接触过高等数学&#xff0c;可是又太想去了解。所以我计划开始慢慢学习它。…...

在 IntelliJ IDEA(2024) 中创建 JAR 包步骤

下是在 IntelliJ IDEA 中创建 JAR 包的详细的步骤&#xff1a; ​1. 选择File -> Project Structure->Artifacts&#xff0c; (1)点击➕新建&#xff0c;如下图所示&#xff1a; (2)选择JAR->Empty (3)输入jar包名称&#xff0c;确定输出路径 &#xff08;4&#…...

『PostgreSQL』PGSQL备份与还原实操指南

&#x1f4e3;读完这篇文章里你能收获到 了解逻辑备份与物理备份的区别及适用场景&#x1f50d;。掌握全库、指定库、指定表备份还原的命令及参数&#x1f4dd;。学会如何根据业务需求选择合适的备份策略&#x1f4ca;。熟悉常见备份还原问题的排查与解决方法&#x1f527;。 …...

Mentalab Explore 在低密度 EEG 系统中的创新应用

在当今科技飞速发展的时代&#xff0c;脑电图&#xff08;EEG&#xff09;技术已成为神经科学研究、医疗诊断和教育领域广泛使用的工具。Mentalab Explore 作为一款专为灵活性和高效性设计的便携式低密度 EEG 系统&#xff0c;凭借其性能和多样的应用场景&#xff0c;正引领着便…...

Ubuntu 24.04.2 允许 root 登录桌面、 ssh 远程、允许 Ubuntu 客户机与主机拖拽传递文件

允许 root 登录桌面 修改 /etc/pam.d/gdm-autologin , /etc/pam.d/gdm-password 加 # 以注释掉 auth required pam_succeed_if.so user ! root quiet_success 允许 root 通过 ssh 登录 修改 /etc/ssh/sshd_config ... #PermitRootLogin prohibit-password PermitRootLogin …...

ngx_openssl_create_conf

ngx_openssl_create_conf 声明在 src\event\ngx_event_openssl.c static void *ngx_openssl_create_conf(ngx_cycle_t *cycle); 定义在 src\event\ngx_event_openssl.c static void * ngx_openssl_create_conf(ngx_cycle_t *cycle) {ngx_openssl_conf_t *oscf;oscf ngx_…...

数学 二次函数

二次函数 就是计算一个抛物线。 抛物线的基本公式&#xff1a; 重点中的重点就是解决&#xff1a; &#xff08;开口方向&#xff1a; 对称轴&#xff0c;顶点&#xff0c;交点&#xff09; 这里的 y 和 x 就是 这个抛物线的个个点的坐标连成的线。 a 的正负 决定和大小决定…...

系统架构的评估的系统的质量属性

体系结构苹果可以针对一个体系结构&#xff0c;也可以针对一组体系结构。 体系结构评估过程中&#xff0c;评估人员所关注的是系统的质量属性&#xff0c;所有评估方法所普遍关注的质量属性有以下几个&#xff1a;性能、可靠性&#xff08;容错&#xff0c;健壮性&#xff09;…...

Facebook 的历史与发展:从校园网站到全球社交平台

引言 Facebook&#xff0c;这个全球最大的社交网络平台之一&#xff0c;其发展历程充满了创新和变革。从最初的校园网站到如今的全球社交平台&#xff0c;Facebook 不仅改变了人们的沟通方式&#xff0c;也重塑了信息传播和社交互动的模式。 起源&#xff1a;校园内的点子 Fa…...

开源、创新与人才发展:机器人产业的战略布局与稚晖君成功案例解析

目录 引言 一、开源&#xff1a;机器人产业的战略布局 促进技术进步和生态建设 吸引人才和合作伙伴 建立标准和网络效应 降低研发风险与成本 二、稚晖君&#xff1a;华为"天才少年计划"的成功典范 深厚的技术积累与动手能力 强烈的探索和创新意识 持续公开…...

Visual Studio 2022新建c语言项目的详细步骤

步骤1&#xff1a;点击创建新项目 步骤2&#xff1a;到了项目模板 --> 选择“控制台应用” (在window终端运行代码。默认打印"Hello World") --> 点击 “下一步” 步骤3&#xff1a;到了配置新项目模块 --> 输入“项目名称” --> 更改“位置”路径&…...

利用FatJar彻底解决Jar包冲突(三)

利用FatJar彻底解决Jar包冲突 Spring 容器的加载与隔离⽀持注解配置⽂件定位与容器初始化嵌套Spring容器的加载 隔离优化EagleEye traceId不⼀致问题原因解决 Spring 容器的加载与隔离 ⽀持注解 这个⽐较容易&#xff0c;主要是我们之前的应⽤不⽀持⼆⽅包内部的注解&#xf…...

【TMS570LC4357】之工程创建

备注&#xff1a;具体资料请在官网海淘.TMS570LC4357资料 1. 下载软件 官网下载对应的编译编辑工具如下图&#xff0c;主要是这两个&#xff0c;其它Flash工具等酌情考虑 安装软件&#xff0c;一直next就可以。安装后新建工程 2. 新建工程 如果不知道怎么建工程&#xff0…...

工作记录 2016-12-22

工作记录 2016-12-22 更新的问题 1、修改了Job Summary的Bill Amount的Bug。 2、修改了Account #的宽度。 3、修改了Clearinghouse Status的默认查询的条件。 4、修改了Upload Files的Add File的bug。 5、Pending Pool、Missing Infos加了Write Off&#xff0c;修改了Histor…...

若依-导出后端解析

针对若依框架微服务版本学习 若依导入导出功能的具体使用详见&#xff1a;后台手册 | RuoYi 1.导出逻辑&#xff1a; 导出文件的逻辑是先创建一个临时文件&#xff0c;等待前端请求下载结束后马上删除这个临时文件。但是有些下载插件&#xff0c;例如迅雷&#xff08;他们是二…...

【QT5 Widgets示例】记事本:(二)界面设计

文章目录 记事本&#xff1a;&#xff08;二&#xff09;界面设计设置窗口标题和图标创建菜单工具栏创建文本框 记事本&#xff1a;&#xff08;二&#xff09;界面设计 设置窗口标题和图标 标题 点击窗口&#xff0c;修改windowTitle项 图标 点击windowIcon 倒三角&#xf…...

MPPT与PWM充电原理及区别详解

MPPT&#xff08;最大功率点跟踪&#xff09;和PWM&#xff08;脉宽调制&#xff09;是太阳能充电控制器中常用的两种技术&#xff0c;它们在原理、效率和适用场景上有显著区别。以下是两者的详细对比&#xff1a; 1. 工作原理 PWM&#xff08;脉宽调制&#xff09; 核心机制…...

K8S 集群搭建——cri-dockerd版

目录 一、工作准备 1.配置主机名 2.配置hosts解析 3.配置免密登录&#xff08;只需要在master上操作&#xff09; 4.时间同步&#xff08;每台节点都要做&#xff0c;必做&#xff0c;否则可能会因为时间不同步导致集群初始化失败&#xff09; 5.关闭系统防火墙 6.配置…...

使用express创建服务器保存数据到mysql

创建数据库和表结构 CREATE DATABASE collect;USE collect;CREATE TABLE info (id int(11) NOT NULL AUTO_INCREMENT,create_date bigint(20) DEFAULT NULL COMMENT 时间,type varchar(20) DEFAULT NULL COMMENT 数据分类,text_value text COMMENT 内容,PRIMARY KEY (id) ) EN…...

ubuntu-学习笔记-nginx+php

nginxphp nginx下载nginx配置nginx.conf php其他 记录一下在ubuntu中nginxphp部署tp项目 nginx nginx就是正常下载 下载nginx sudo apt-get install nginx tp项目版本是3.2&#xff0c;通过设置路由&#xff0c;以域名/api.php/控制器/xxx的格式进行api的调用&#xff0c;文…...

打造智能聊天体验:前端集成 DeepSeek AI 助你快速上手

DeepSeek AI 聊天助手集成指南 先看完整效果&#xff1a; PixPin_2025-02-19_09-15-59 效果图&#xff1a; 目录 项目概述功能特点环境准备项目结构组件详解 ChatContainerChatInputMessageBubbleTypeWriter 核心代码示例使用指南常见问题 项目概述 基于 Vue 3 TypeScrip…...

github生成badges的方法

在Github页面上生成类似下面这样的badge的方法 你可以通过以下步骤在GitHub个人主页的README中创建类似的技术栈徽章&#xff1a; 一、使用 Shields.io 生成徽章 Shields.io 是一个开源徽章生成工具&#xff0c;支持自定义文本、颜色、图标等参数。 1. 基础模板 https://…...

vulnhub靶场渗透之SickOs1.2渗透教程,计划任务提权、chkrootkit提权

vulnhub靶场渗透之SickOs1.2渗透教程&#xff0c;计划任务提权、chkrootkit提权 一、信息收集 1、首先拿到靶场先扫一下ip 2025.3.7 AM 8&#xff1a;36 arp-scan -l 扫描同网段 nmap -sP 192.168.66.24/02、指纹扫描 nmap -sS -sV 192.168.66.130 指纹扫描PORT STATE S…...

Ubuntu系统部署.NET 8网站项目

一、使用XShell连接 Ubuntu系统初次连接时默认的用户名为&#xff1a;ubuntu&#xff0c;使用此用户名与系统登录密码进行连接。 登录成功效果如下图&#xff1a; 二、root用户登录 linux下有超级用户&#xff08;root&#xff09;和普通用户&#xff0c;普通用户不能直接操…...

CI/CD—Jenkins配置一次完整的jar自动化发布流程

背景&#xff1a; 实现设想&#xff1a; 要创建自动化发布&#xff0c;需要准备一台测试服务器提前安装好java运行所需的环境&#xff0c;JDK版本最好和Windows开发机器上的版本一致&#xff0c;在Jenkins上配置将构建好的jar上传到测试服务器上&#xff0c;测试服务器自动启动…...

【Academy】Web 缓存欺骗 ------ Web cache deception

Web 缓存欺骗 ------ Web cache deception 1. 概述2. Web 缓存2.1 缓存键2.2 缓存规则 3. 构建 Web 缓存欺骗攻击3.1 使用缓存破坏器3.2 检测缓存的响应 4. 利用静态扩展缓存规则4.1 路径映射差异4.2 利用路径映射差异4.3 分隔符差异4.4 利用分隔符差异4.5 分隔符解码差异4.6 利…...

MATLAB表格Table与时间序列Timetable的高效操作方法

MATLAB中的表格&#xff08;Table&#xff09; 和 时间序列&#xff08;Timetable&#xff09; 是处理结构化数据和时间相关数据的核心工具。以下从基础操作到高级技巧&#xff0c;分步骤详解其使用方法。 一、创建与基础操作 1. 表格&#xff08;Table&#xff09;的创建与访…...

【leetcode hot 100 21】合并两个有序链表

解法一&#xff1a;新建一个链表存放有序的合并链表。当list1和list2至少有一个非空时&#xff0c;返回非空的&#xff1b;否则找出两个链表的最小值作为新链表的头&#xff0c;然后依次比较两链表&#xff0c;每次都先插入小的值。 /*** Definition for singly-linked list.*…...

本地部署 OpenManus 保姆级教程(Windows 版)

一、环境搭建 我的电脑是Windows 10版本&#xff0c;其他的没尝试&#xff0c;如果大家系统和我的不一致&#xff0c;请自行判断&#xff0c;基本上没什么大的出入啊。 openManus的Git地址&#xff1a;https://github.com/mannaandpoem/OpenManus 根据官网的两种安装推荐方式如…...

20250310:OpenCV mat对象与base64互转

代码: https://github.com/ReneNyffenegger/cpp-base64 指南:https://renenyffenegger.ch/notes/development/Base64/Encoding-and-decoding-base-64-with-cpp/ 实操:...

WPS的付费功能,这款软件可完美平替

因为作者有工作上的需求加上WPS使用批量提取图片需要会员&#xff0c;所以自己使用cursor制作了一个从excel中提取图片的工具。 支持提取Excel中的浮动图片和根据图片链接来下载图片。 Excel Image Extractor Excel图片提取工具 软件的功能非常强大&#xff0c;支持提取Excel中…...

L1-088 静静的推荐

L1-088 静静的推荐 - 团体程序设计天梯赛-练习集 (pintia.cn) 题解 这里代码很简单&#xff0c;但是主要是循环里面的内容很难理解&#xff0c;下面是关于循环里面的内容理解&#xff1a; 这里 n 10 表示有 10 个学生&#xff0c;k 2 表示企业接受 2 批次的推荐名单&#…...

NS3学习——运行自定义拥塞控制算法步骤

目录 一、添加优化后的代码文件 二、更改CMakeLists文件中内容 三、重新配置和编译ns-3 四、常见问题 目的&#xff1a;想在tcp拥塞控制算法的基础上进行优化改进&#xff0c;之后在ns3中运行优化后的算法&#xff0c;即自定义拥塞控制算法&#xff1b; 以tcpVegas算法为…...

前端开发中的常见设计模式:全面解析与实践

1. 引言 1.1 设计模式的重要性 设计模式是软件开发中经过验证的解决方案&#xff0c;能够帮助开发者解决常见的设计问题。在前端开发中&#xff0c;合理使用设计模式可以提高代码的可维护性、可扩展性和复用性。 1.2 本文的目标 本文旨在全面解析前端开发中常见的设计模式&…...

VSCode 2025最新 前端开发必备插件推荐汇总(提效指南)

&#x1f31f;前言: 如果你是一名前端开发工程师&#xff0c;合适的开发工具能大大提高工作效率。Visual Studio Code (VSCode) 凭借其轻量级、高扩展性的特点&#xff0c;已成为众多前端开发者在win系电脑的首选IDE。 名人说&#xff1a;博观而约取&#xff0c;厚积而薄发。—…...

【redis】redis的单线程模型为什么效率高?

文章目录 单线程模型单线程的 Redis 为什么效率高&#xff1f;速度快&#xff1f;IO多路复用epoll 单线程模型 Redis 只使用一个线程&#xff0c;处理所有的命令请求。不是说一个 Redis 服务器进程内部只有一个线程&#xff0c;其实也有多个线程&#xff0c;多个线程是在处理网…...

scala的集合

scala的集合系统的区分了可变&#xff08; mutable &#xff09;和不可变&#xff08;immutable &#xff09;集合。 mkString(seq:String)&#xff1a;方法是将原字符串使用特定的字符串seq分割。 mkString(statrt:String,seq:String,end:String)&#xff1a;方法是将原字符…...

Flink状态管理深度探索:从Keyed State到分布式快照

Flink状态管理深度探索:从Keyed State到分布式快照 在大数据实时计算领域,Apache Flink凭借其精准的状态管理能力成为行业标杆。本文将从状态管理的核心机制出发,结合金融行业PB级数据处理实践,深入解析状态后端、容错机制与大规模优化策略。 一、Flink状态管理核心架构 …...

Android 11 DAC和MAC

在 Android 11 中,DAC(Discretionary Access Control,自主访问控制) 和 MAC(Mandatory Access Control,强制访问控制) 是两种不同的访问控制机制,主要用于 权限管理、安全性 以及 进程间访问控制。 1. DAC(自主访问控制) DAC(Discretionary Access Control,自主访…...

平衡二叉树(AVL树)

平衡二叉树是啥我就不多说了&#xff0c;本篇博客只讲原理与方法。 首先引入平衡因子的概念。平衡因子&#xff08;Balance Factor&#xff09;&#xff0c;以下简称bf。 bf 右子树深度 - 左子树深度。平衡结点的平衡因子可为&#xff1a;-1&#xff0c;0&#xff0c;1。除此…...

SSM架构 +java后台 实现rtsp流转hls流,在前端html上实现视频播放

序言&#xff1a;书接上文&#xff0c;我们继续 SSM架构 NginxFFmpeg实现rtsp流转hls流&#xff0c;在前端html上实现视频播放 步骤一&#xff1a;把rtsp流转化为hls流&#xff0c;用Java代码进行转换 package com.tools;import java.io.BufferedReader; import java.io.IOExc…...

贪心算法--

1.柠檬水找零 link:860. 柠檬水找零 - 力扣&#xff08;LeetCode&#xff09; code class Solution { public:bool lemonadeChange(vector<int>& bills) {// 贪心算法&#xff0c; 优先花出大面额bill&#xff0c; 尽可能保护小面额billint five 0, ten 0;// 不…...

【从0到1搞懂大模型】神经网络的实现:数据策略、模型调优与评估体系(3)

一、数据集的划分 &#xff08;1&#xff09;按一定比例划分为训练集和测试集 我们通常取8-2、7-3、6-4、5-5比例切分&#xff0c;直接将数据随机划分为训练集和测试集&#xff0c;然后使用训练集来生成模型&#xff0c;再用测试集来测试模型的正确率和误差&#xff0c;以验证…...

CTF工具集合-持续更新

工具地址https://github.com/huan-cdm/ctf_tools工具介绍&#xff1a; 1.ARCHPR&#xff1a;压缩包密码破解工具 2.StegSolve-1.4.jar&#xff1a;隐写图片查看工具 3.ctf_decrypt_tool.rar&#xff1a;随波逐流CTF编码工具 4.010_Editor_All_Versions_For_Windows_CracKed.…...

小方摄像头接入本地服务器的方法

最早众筹时买了几个小方摄像头&#xff0c;后来嫌弃分辨率&#xff0c;就淘汰吃灰好几年&#xff0c;最近想折腾个摄像头识别的小项目&#xff0c;秉着不投入先凑合跑起来的原则&#xff0c;想到了尘封已久的小方&#xff0c;想看看能不能通过网络拉取数据流。 搜索了下&#x…...

取反符号~

取反符号 ~ 用于对整数进行按位取反操作。它会将二进制表示中的每一位取反&#xff0c;即 0 变 1&#xff0c;1 变 0。 示例 a 5 # 二进制表示为 0000 0101 b ~a # 按位取反&#xff0c;结果为 1111 1010&#xff08;补码表示&#xff09; print(b) # 输出 -6解释 5 的二…...

Jenkins实现自动化构建与部署:上手攻略

一、持续集成与Jenkins核心价值 1.1 为什么需要自动化构建&#xff1f; 在现代化软件开发中&#xff0c;团队每日面临以下挑战&#xff1a; 高频代码提交&#xff1a;平均每个开发者每天提交5-10次代码。多环境部署&#xff1a;开发、测试、预发布、生产环境需频繁同步。复杂…...

爱普生温补晶振 TG5032CFN高精度稳定时钟的典范

在科技日新月异的当下&#xff0c;众多领域对时钟信号的稳定性与精准度提出了极为严苛的要求。爱普生温补晶振TG5032CFN是一款高稳定性温度补偿晶体振荡器&#xff08;TCXO&#xff09;。该器件通过内置温度补偿电路&#xff0c;有效抑制环境温度变化对频率稳定性的影响&#x…...

【Java 面试 八股文】计算机网络篇

操作系统篇 1. 什么是HTTP? HTTP 和 HTTPS 的区别?2. 为什么说HTTPS比HTTP安全? HTTPS是如何保证安全的&#xff1f;3. 如何理解UDP 和 TCP? 区别? 应用场景?3.1 TCP 和 UDP 的特点3.2 适用场景 4. 如何理解TCP/IP协议?5. DNS协议 是什么&#xff1f;说说DNS 完整的查询…...