【MySQL 进阶之路】SQL 性能分析

4.SQL 性能分析笔记

在 MySQL 中进行性能分析是数据库优化的重要一环。通过识别性能瓶颈,优化 SQL 查询和数据库配置,可以显著提高应用的响应速度和吞吐量。以下是 MySQL 性能分析的进阶笔记,涵盖了常见的性能分析方法和工具。

1. 查询缓存(Query Cache)

MySQL 提供了查询缓存(query_cache),缓存已经执行过的查询结果,以提高后续相同查询的执行速度。但它的使用效果在高并发的情况下可能会降低性能,从 MySQL 5.7.20 开始, 查询缓存已经被废弃。

启用查询缓存:
sql 复制代码
SET GLOBAL query_cache_type = 1;
SET GLOBAL query_cache_size = 1048576;  -- 1MB 缓存
注意事项:
  • 查询缓存对于 INSERTUPDATEDELETE 等修改数据的操作没有太大作用,反而可能增加性能开销。
  • 查询缓存适合读取频繁但变化较少的场景。

2. EXPLAIN 分析查询执行计划

EXPLAIN 是分析 SQL 查询执行计划的一个常用工具,它帮助我们了解 MySQL 如何执行查询,包括使用哪些索引、如何扫描数据等。其基本用法如下:

sql 复制代码
EXPLAIN SELECT * FROM users WHERE age > 25;

EXPLAIN 输出解释:

字段 含义
id 查询的标识符,标识不同的查询步骤
select_type 查询类型,例如:SIMPLE(简单查询)、PRIMARY(最外层查询)、SUBQUERY(子查询)等
table 表名,表示该步骤操作的表
type 连接类型,表示 MySQL 如何查找数据,性能由 type 的值决定,常见的有:ALL(全表扫描)、index(索引扫描)、range(范围扫描)、ref(使用索引进行查找)、const(常数查询)等
possible_keys 可能使用的索引
key 实际使用的索引
key_len 使用的索引长度
ref 表示索引是如何与其他表的字段进行连接的
rows 扫描的行数估计值
Extra 额外信息,表示查询执行的附加信息,如 Using whereUsing index

优化建议:

  • 如果 typeALL,意味着查询使用了全表扫描,可以考虑添加合适的索引来优化。
  • 如果 rows 数量很大,可能需要进一步检查查询条件和表结构。
  • 关注 Extra 字段,查看是否存在全表扫描、临时表等性能瓶颈。

3. 慢查询日志

MySQL 提供了慢查询日志(slow_query_log),记录所有执行时间超过指定阈值的查询。启用慢查询日志后,可以分析慢查询并优化。

启用慢查询日志:
sql 复制代码
SET GLOBAL slow_query_log = 1;
SET GLOBAL slow_query_log_file = '/path/to/slow-query.log';
SET GLOBAL long_query_time = 2;  -- 查询时间大于1秒的都会被记录
分析慢查询日志:

通过 mysqldumpslowpt-query-digest 等工具分析慢查询日志,找出哪些查询执行时间过长、哪些查询需要优化。

3. 查看 SQL 执行频次

通过执行 SHOW GLOBAL STATUS LIKE 'Com%' 命令,可以查看 MySQL 系统中所有执行过的 SQL 命令的频次统计。这些统计数据可以帮助我们了解哪些 SQL 操作在系统中最为频繁,并根据执行频次来判断是否需要优化某些查询或操作。

常见的 Com% 状态变量:
  • Com_select :执行 SELECT 查询的次数
  • Com_insert :执行 INSERT 查询的次数
  • Com_update :执行 UPDATE 查询的次数
  • Com_delete :执行 DELETE 查询的次数
  • Com_create_table:创建表的次数
  • Com_drop_table:删除表的次数
  • Com_commit:事务提交的次数
  • Com_rollback:事务回滚的次数

通过查看这些统计信息,您可以识别出哪些操作是系统中频繁执行的。例如,如果 Com_select 的值异常高,而其他如 Com_insertCom_update 的值较低,这可能意味着查询操作频繁,而数据修改较少,您可以从查询优化方面入手。

示例:
sql 复制代码
SHOW GLOBAL STATUS LIKE 'Com%';

输出示例:

sql 复制代码
+------------------------+---------+
| Variable_name          | Value   |
+------------------------+---------+
| Com_select             | 150000  |
| Com_insert             | 50000   |
| Com_update             | 20000   |
| Com_delete             | 10000   |
| Com_create_table       | 5       |
| Com_drop_table         | 3       |
+------------------------+---------+

通过分析这些数据,您可以看到最频繁的操作类型,从而做针对性的优化。


4. 查询性能分析

SHOW PROFILES 命令用于查看 SQL 查询的执行性能,可以帮助开发人员查看查询执行的各个阶段耗时,进一步发现查询性能瓶颈。SHOW PROFILES 返回的是在当前会话中执行过的所有 SQL 查询的时间统计信息,包括每个查询的总执行时间、各个阶段的时间消耗等。

启用 profiling 功能:

在 MySQL 5.0 及以上版本中,profiling 默认是禁用的。如果需要使用该功能,您需要先通过以下命令启用它:

sql 复制代码
SET profiling = 1;
使用 SHOW PROFILES 查询执行时间:

执行完查询后,可以使用 SHOW PROFILES 来查看执行过的 SQL 语句以及各个阶段的执行时间。

sql 复制代码
SHOW PROFILES;

输出示例:

sql 复制代码
+------+------------------------------------------+-----------+
| Query_ID | Query                                  | Duration  |
+---------+----------------------------------------+-----------+
| 1       | SELECT * FROM users WHERE age > 25     | 0.002300  |
| 2       | SELECT * FROM orders WHERE order_id=123| 0.001500  |
+---------+----------------------------------------+-----------+
  • Query_ID: 查询的唯一标识符
  • Query: 执行的 SQL 查询
  • Duration: 执行时间(秒)
查看查询执行的详细阶段:

通过 SHOW PROFILE FOR QUERY <query_id> 可以查看指定查询的详细执行阶段信息,如解析、优化、执行等各个阶段的耗时。

sql 复制代码
SHOW PROFILE FOR QUERY 1;

输出示例:

sql 复制代码
+--------------------------+----------+
| Status                   | Duration |
+--------------------------+----------+
| starting                 | 0.000030 |
| reading from net         | 0.000340 |
| preparing                | 0.000020 |
| executing                | 0.000250 |
| sending data             | 0.000180 |
| end                      | 0.000010 |
| query end                | 0.000080 |
| closing tables           | 0.000060 |
| freeing items            | 0.000020 |
| cleaning up              | 0.000010 |
+--------------------------+----------+

字段解释

  • Status : 查询的执行状态(例如 startingexecutingsending data 等)
  • Duration: 每个阶段的执行时间,单位是秒

通过分析这些阶段的耗时,您可以找出查询中最耗时的部分,并做针对性的优化。例如,如果 reading from net 阶段耗时较长,可能是因为网络延迟或查询结果集过大;如果 sending data 阶段耗时较长,可能是因为 MySQL 在处理大量数据。


总结

MySQL 性能优化是一个不断调优的过程,从硬件配置到查询结构优化再到索引设计,都需要全面考虑。利用 EXPLAIN 分析执行计划、慢查询日志、索引优化、内存调优等手段,可以有效提升数据库的性能。在高并发、大数据量的场景下,分库分表、查询缓存、连接优化等技术也是不可或缺的工具。

相关推荐
老王笔记1 分钟前
MySQL如何区分幻读和不可重复读
数据库·mysql
不爱学习的啊Biao2 分钟前
【08】MySQL复杂查询:子查询语句详解与示例
数据库·mysql·子查询
s***g54010 分钟前
MySQL-操作数据库备份与恢复
数据库·mysql
程序猿进阶1 小时前
Tomcat 都有哪些核心组件
java·开发语言·后端·面试·性能优化·tomcat·firefox
大筒木老辈子2 小时前
Linux笔记---进程:进程替换
linux·服务器·笔记
不会聊天真君6473 小时前
爬虫(JAVA笔记第四十期)
java·笔记
青云交3 小时前
大数据新视界 -- Hive 元数据管理:核心元数据的深度解析(上)(27 / 30)
hive·sql·元数据管理·数据目录·核心元数据·元数据存储·元数据操作·大数据管理基石
青云交3 小时前
大数据新视界 -- Hive 数据湖集成与数据治理(下)(26 / 30)
hive·sql·数据治理·数据管理·数据湖集成·大数据集成·数据质量保障·数据湖优化
吃着火锅x唱着歌4 小时前
PHP7内核剖析 学习笔记 第一章 PHP基础架构
笔记·学习·php
亦枫Leonlew7 小时前
三维测量与建模笔记 - 5.3 光束法平差(Bundle Adjustment)
笔记·计算机视觉·三维重建·光束法平差