explain 分析 SQL 语句

数据库优化 学习笔记

一、影响服务器性能的几个方面


1.1、影响因素

  1. 服务器硬件

  2. 服务器的操作系统

  3. 数据库存储引擎的选择

  4. 数据库参数配置

  5. 数据库结构设计和SQL语句


1.2、SQL 性能下降原因

  1. 查询语句写的不好

  2. 索引失效

  3. 关联查询太多 join

  4. 服务器调优及各个参数设置


1.3、SQL 加载顺序

	手写 SQL 的顺序  ≠  机读的 SQL 顺序

  • 手写SQL的顺序
	select 
	distinct <select _list>
	from <left_table>
	join  <right_table> on <join_codition>
	where <where_condition>
	group by <group_by_list>
	having <having_condition>
	order by <order_by_condition>
	limit <limit number>

  • 机读的SQL顺序
	from <left_table>
	on <join_codition>
	<right_type> join <right_table>
	where <where_condition>
	group by <group_by_list>
	having <having_condition>
	select 
	distinct <select _list>
	order by <order_by_condition>
	limit <limit number>

1.4、MySQL常见瓶颈

  • CPU: CPU 在饱和的时候一般发生在数据装入内存或从磁盘读取数据的时候。

  • IO: 磁盘 I/O 瓶颈发生在装入数据远大于内存容量的时候。

  • 服务器硬件的性能瓶颈。



二、explain 分析 SQL


2.1、explain 是什么?

        使用 explain 关键字可以模拟优化器执行 SQL 查询语句,从而知道 MySQL 是如何处理你的 SQL 语句的。

2.2、explain 能干嘛?

  • 查看执行该 SQL 语句表的读取顺序

  • 查看执行该 SQL 语句数据读取操作的操作类型

  • 查看执行该 SQL 语句哪些索引可以使用

  • 查看执行该 SQL 语句哪些索引被实际使用

  • 查看执行该 SQL 语句表之间的引用

  • 查看执行该 SQL 语句每张表有多少行被优化器查询

2.3、explain 怎么玩?

	-- explain + SQL 语句
	-- 如:
	explain select * from test;



三、explain 字段解释


3.1、id —— 表的读取顺序(需关注)

select 查询顺序号,包含一组数字,表示查询中执行 select 字句或操作表的顺序。有两种情况:

  1. id 相同,执行顺序由上至下;
  2. id 不同,如果是子查询,id 的序号会递增,id 值越大则优先级越高越先被执行。
    在这里插入图片描述

3.2、select_type —— 数据读取操作的操作类型

  1. simple: 简单的 select 查询,查询中不包含子查询 或者 union

  2. primary: 查询中若包含任何复杂的子部分,最外层查询则被标记。就是最后加载的那个,执行顺序排最后的那个表的 select_type 为 primary

  3. subquery: 在 select 或 where 列表中包含了子查询

  4. union: 若第二个 select 出现在 union 之后,则被标记为 union ,
    union 简单使用:select * from t1 union select * from t4

  5. union result: 从 union 表获取结果的 select

3.3、table —— 显示这一行的数据是关于那张表的

3.4、partitions —— 查询访问的分区

3.5、type —— 可获知 sql 语句的执行效率(很重要)
在这里插入图片描述
从最好到最差依次是:

	-- system 和 const 都是不太现实的
	system > const > eq_ref > ref > range > index > ALL
  • system: 表只有一行记录(等于系统表),这是 const 类型的特例

  • const: 表示通过索引一次就找到了,const 用于比较 primary key

  • eq_ref: 唯一索引扫描,对于每个索引键,表中只有一条记录与之匹配

  • ref: 非唯一性索引扫描,返回匹配某个单独值得所有行,本质上也是一种索引访问,它返回所有匹配某个单独值的行

  • range: 只检索给定范围的行,使用一个索引来选择行

  • index: Full Index Scan,index 与 ALL区别为 index 类型只遍历索引树

  • ALL: 将遍历全表找到匹配的行(查询的时候尽量不要用 select * ,否则很可能就是 ALL)

3.6、possible_keys —— 显示可能应用在这张表中的索引(一个或多个)

3.7、key —— 实际使用到的索引(需关注注)

  • 执行该 SQL 语句时,实际使用的索引。如果为null,则没有使用索引。

  • 若查询的表中存在复合索引和主键索引,则 key 列表中显示复合索引。

3.8、key_len —— 索引长度

  • 表示索引中使用的字节数,可通过该列计算查询中使用的索引长度。在不损失精确性的情况下,长度越短越好

  • key_len 显示的值为索引字段的最大可能长度,并非实际使用长度,即 key_len 是根据表定义计算而得,不是通过表内检索出的

索引长度计算(了解)

	varchr(24)变长字段且允许NULL
	24*(Character Set:utf8=3,gbk=2,latin1=1)+1(NULL)+2(变长字段)
		--例: varchr(24)变长字段且允许NULL, 编码为 utf8,
		--则 key_len = 24 * 3 + 1 + 2
		
	varchr(10)变长字段且不允许NULL  
	10*(Character Set:utf8=3,gbk=2,latin1=1)+2(变长字段)

	char(10)固定字段且允许NULL      
	10*(Character Set:utf8=3,gbk=2,latin1=1)+1(NULL)

	char(10)固定字段且不允许NULL    
	10*(Character Set:utf8=3,gbk=2,latin1=1)

3.9、ref —— 显示索引相应表的哪一列被使用到了

3.10、rows

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

在这里插入图片描述

3.11、Extra —— 包含不适合在其他列中显示但十分重要的额外信息(重点关注下面的前两个)

  • Using filesort: 说明 mysql 会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取,MySQL 中无法利用索引完成的排序操作称为 " 文件内排序 "。
    若 Extra 中出现这个,那么说明 SQL 语句必须做优化了。

  • Using temporary: 使用 临时表保存中间结果,MySQL 在对查询结果排序时使用临时表。(查询时创建临时表 → 结果存放在临时表中 → 查询结束删除临时表)
    若出现这个, SQL 语句也要优化了。(表太长,可以在语句后面加“\G”不用分号,改变显示形式)
    在这里插入图片描述

  • Using index: 使用了索引,避免了全表扫描。

  • Using where: 使用了 where 过滤。

  • Using join buffer: 使用了连接缓存。

  • impossible where: 不可能的条件,where 子句的值总是 false。

发布了85 篇原创文章 · 获赞 0 · 访问量 1251

猜你喜欢

转载自blog.csdn.net/qq_43621629/article/details/103683136