MySQL数据库优化之不能不懂的 Explain 优化

参考博客:
https://blog.youkuaiyun.com/why15732625998/article/details/80388236 [MySQL高级](一) EXPLAIN用法和结果分析

1. EXPLAIN简介

使用EXPLAIN关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句的。分析你的查询语句或是表结构的性能瓶颈。

通过EXPLAIN,我们可以分析出以下结果:

  • 表的读取顺序
  • 数据读取操作的操作类型
  • 哪些索引可以使用
  • 哪些索引被实际使用
  • 表之间的引用
  • 每张表有多少行被优化器查询
2. EXPLAIN 语法

EXPLAIN + 查询语句
在这里插入图片描述

3. EXPLAIN 执行计划各字段含义
EXPLAIN 字段解释
idselect查询的序列号,包含一组数字,表示查询中执行select子句或操作表的顺序
select_type用来表示查询的类型,主要是用于区别普通查询、联合查询、子查询等的复杂查询
table表示执行的表
type显示的是查询使用了哪种类型
prossible_key显示可能应用在这张表中的索引,一个或多个
key实际使用到的索引
key_len表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度,在不损失精确性的情况下,长度越短越好。key_len显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len是根据表定义计算而得,不是通过表内检索出的。
ref显示索引的那一列被使用了,如果可能的话,最好是一个常数。哪些列或常量被用于查找索引列上的值。
rows根据表统计信息及索引选用情况,大致估算出找到所需的记录所需要读取的行数,也就是说,用的越少越好
Extra包含不适合在其他列中显式但十分重要的额外信息
3.1 id
  • id相同,执行顺序由上至下
    在这里插入图片描述
    [总结] 加载表的顺序如上图table列所示:om,oi,dm

  • id不同,如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行

在这里插入图片描述

3.2 select_type
select_type解释
SIMPLE简单的select查询,查询中不包含子查询或者UNION
PRIMARY查询中若包含任何复杂的子部分,最外层查询则被标记为PRIMARY
SUBQUERY在SELECT或WHERE列表中包含了子查询
DERIVED在FROM列表中包含子查询,MySQL会递归执行这些子查询,把结果放在临时表中
UNION若第二个SELECT出现在UNION之后,则被标记为UNION
UNION RESULT从UNION表获取结果的SELECT
3.3 table

当前执行的表

3.4 type

type所显示的是查询使用了哪种类型,type包含的类型包括如下图所示的几种:

type解释
system表只有一行记录,const的特例
const表示通过索引一次就找到了,const用于比较primary key 或者unique索引 在这里插入图片描述
eq_ref唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见于主键或唯一索引扫描
ref非唯一性索引扫描,返回匹配某个单独值的所有行,本质上也是一种索引访问,它返回所有匹配某个单独值的行,然而,它可能会找到多个符合条件的行,所以他应该属于查找和扫描的混合体。
range只检索给定范围的行,使用一个索引来选择行,key列显示使用了哪个索引,一般就是在你的where语句中出现between、< 、>、in等的查询,这种范围扫描索引比全表扫描要好,因为它只需要开始于索引的某一点,而结束于另一点,不用扫描全部索引。
indexFull Index Scan,Index与All区别为index类型只遍历索引树。这通常比ALL快,因为索引文件通常比数据文件小。(也就是说虽然all和Index都是读全表,但index是从索引中读取的,而all是从硬盘读取的)
allFull Table Scan 将遍历全表以找到匹配的行
3.5 possible_keys 和 key

possible_keys
显示可能应用在这张表中的索引,一个或多个。查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询实际使用。
key

  • 实际使用的索引,如果为NULL,则没有使用索引。(可能原因包括没有建立索引或索引失效)
    在这里插入图片描述
  • 查询中若使用了覆盖索引(select 后要查询的字段刚好和创建的索引字段完全相同),则该索引仅出现在key列表中
    在这里插入图片描述
3.6 key_len

表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度,在不损失精确性的情况下,长度越短越好。key_len显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len是根据表定义计算而得,不是通过表内检索出的。

在这里插入图片描述

3.7 ref

显示索引的那一列被使用了,如果可能的话,最好是一个常数。哪些列或常量被用于查找索引列上的值。
在这里插入图片描述

3.8 rows

根据表统计信息及索引选用情况,大致估算出找到所需的记录所需要读取的行数,也就是说,用的越少越好

在这里插入图片描述


参考博客:
https://blog.youkuaiyun.com/why15732625998/article/details/80388236 [MySQL高级](一) EXPLAIN用法和结果分析

<think>嗯,用户问的是如何诊断和降低MySQL数据库CPU占用飙升的问题。我得先回忆一下之前学过的相关知识,然后结合提供的引用内容来组织答案。首先,根据引用3,处理步骤大概分为几个阶段:先用top命令确认是否是MySQL导致的,然后通过show processlist查看会话,找出消耗高的SQL,接着分析执行计划、索引和数据量。可能需要优化SQL者调整配置。 接下来,我需要把步骤拆解得更详细些,让用户能一步步跟着操作。比如诊断阶段,可能包括检查系统负载、定位高消耗的SQL、分析执行计划。然后优化阶段包括SQL优化、索引调整、配置调优,还有应急措施比如终止会话者增加资源。另外,引用里提到了kill会话和使用连接池,这些也要提到。 还要注意用户可能太懂专业术语,所以需要用简单的中文解释清楚每个步骤的目的和操作方法。比如,explain命令的作用,慢查询日志怎么开启,索引该怎么添加。同时,要确保LaTeX格式正确,行内公式用$...$,独立公式用$$...$$,但在这个问题里可能用到的数学公式多,过如果有提到性能指标之类的,可能需要用到。 另外,用户可能需要知道如何预防问题再次发生,所以得加上监控和定期维护的建议,比如使用Prometheus者定期清理数据。引用里提到的连接池管理和读写分离也是重要的点,要包含进去。 最后,生成的相关问题要围绕这个主题展开,比如如何分析慢查询、索引优化方法、预防CPU飙升的措施等。确保每个步骤都自然引用提供的参考文献,比如在提到使用top命令时引用3,优化SQL时引用1和3,配置调整引用1和2。 还要检查是否有遗漏的步骤,比如应急处理中的终止会话和扩容,是否都涵盖到了。确保回答结构清晰,分诊断和优化两大部分,每个部分再细分小点,用编号列表让用户容易跟随。代码块部分要正确显示SQL命令和配置示例,比如设置慢查询日志的命令。同时,避免使用Markdown格式,按照用户的要求只用中文回答,保持口语化但专业。</think>### 诊断与降低MySQL数据库CPU占用率的步骤 #### 一、诊断阶段 1. **确认CPU飙升来源** - 使用`top``htop`命令观察系统进程,确认是否为MySQL进程(如`mysqld`)导致CPU过高[^3]。 - 若其他进程导致,需排查系统级问题(如恶意攻击外部服务负载)。 2. **定位高消耗SQL** - 登录MySQL,执行`SHOW FULL PROCESSLIST;`,查看当前活跃会话,筛选`Time`值大且`State`为`Sending data``Sorting result`的SQL。 - 启用慢查询日志辅助定位: ```sql SET GLOBAL slow_query_log = 'ON'; SET GLOBAL long_query_time = 2; -- 记录执行超过2秒的查询 ``` 3. **分析SQL执行计划** - 对高消耗SQL使用`EXPLAIN`命令,检查是否走索引、是否存在全表扫描。 例如:`EXPLAIN SELECT * FROM orders WHERE user_id = 100;`。 --- #### 二、优化阶段 1. **SQL优化** - 重写复杂查询,避免嵌套子查询大表关联。 - 拆分大批量操作(如`DELETE``UPDATE`)为小批次任务,减少锁竞争[^1]。 2. **索引优化** - 为高频查询字段添加索引,例如: ```sql ALTER TABLE orders ADD INDEX idx_user_id (user_id); ``` - 删除冗余索引,避免写操作性能下降[^3]。 3. **配置调优** - 调整`innodb_buffer_pool_size`(通常设为物理内存的70-80%),减少磁盘I/O。 - 限制并发连接数:修改`max_connections`和`thread_cache_size`[^2]。 4. **应急处理** - 终止异常会话:`KILL <process_id>;`。 - 扩容临时资源(如CPU内存),缓解瞬时压力[^1]。 --- #### 三、预防措施 - **监控与告警** 使用工具如Prometheus+Grafana监控MySQL的QPS、慢查询率、连接数等核心指标[^2]。 - **定期维护** 清理历史数据,优化表结构(`OPTIMIZE TABLE`),避免数据碎片化。 - **连接池管理** 使用连接池(如HikariCP)控制连接数,避免频繁创建/销毁连接。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值