mysql优化 - explain

explain

explain可以模拟优化器执行sql查询语句,从而知道mysql是如何处理我们的sql的。分析查询语句或者表结构的性能瓶颈。

  • 语法:Explain + SQL 语句;
    如:Explain select * from user; 会生成如下 SQL 分析结果,下面详细对每个字段进行详解
explain select * from actor;
+----+-------------+-------+------+---------------+------+---------+------+-----
-+-------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows
 | Extra |
+----+-------------+-------+------+---------------+------+---------+------+-----
-+-------+
|  1 | SIMPLE      | actor | ALL  | NULL          | NULL | NULL    | NULL |  204
 |       |
+----+-------------+-------+------+---------------+------+---------+------+-----
-+-------+
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
  • id :select 查询的序列号,包含一组数字,表示查询中select字句或者操作表的顺序。
    1.id相同 :可以认为是一组,执行顺序由上而下。
    2.id不同,子查询的序号会递增,id序号越大,优先级越高,越先被执行。子查询优先级高于主查询。
    3.id相同又不同 :id大的先执行,id相同的由上至下顺序执行。
    衍生=derived

  • select_type:

select_typeinfo
simple简单的select查询,查询中不包括自子查询和union
primary包含复杂的子查询,最外层的查询为primary,最后加载
subqueryselect或者from中包含子查询
derived查询结果放在临时表中的表被标记为derive的,在from列表中包含的子查询被标记为derived,mysql会递归执行这些子查询,把结果保存在临时表中
union若第二个select出现在union后,则被标记为union;若union包含在from字句的子查询中,外层select则被标记为derived
union result两个查询集合的union
  • table :表
  • type(访问类型) :
    常见的type:
typeinfo
system表只有一行记录,等于系统表,这是const的特例,工作中一般不会出现
const将主键索引或者唯一索引放到 where 条件中查询,MySQL 可以将查询条件转变成一个常量,只匹配一行数据,索引一次就找到数据了
eq_ref唯一索引扫描,对于每个索引建,表中只有一条记录与之对应。常见于主键索引和唯一索引
ref不是主键索引,也不是唯一索引,就是普通的索引,可能会返回多个符合条件的行。
range体现在对某个索引进行区间范围检索,一般出现在 where 条件中的 between、and、<、>、in 等范围查找中。
index将所有的索引树都遍历一遍,查找到符合条件的行。索引文件比数据文件还是要小很多,所以比不用索引全表扫描还是要快很多。
all全表扫描

至少达到range级别,最好能达到ref级别。

  • possible keys : 显示这张表可能用到的索引,一个或者多个。查询涉及到的字段上若存在索引,则索引将会被列出,但不一定被实际查询使用。
  • key : 实际使用的索引,如果为NULL,则:1.索引失效 2.没有索引
    若查询中使用了覆盖索引,则索引进出现在key列表中。
  • key_len :表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度,长度越小,B+树中一个节点存的索引相对越多,减少树的深度,可以减少IO次数。
    索引字段的可能的最大长度,并非是实际长度。key_len 是根据表定义得出,并不是表内检测出的。
-- show variables like '%charcter_set%'; 数据库和服务器的字符集
SHOW VARIABLES LIKE 'character_set%'; 
-- show table status from 库名 like '%表名%';显示表的字符集
SHOW TABLE STATUS FROM sakila LIKE '%actor%';

utf8 char(n)里一个字符包含3个字节,总字节为3*n;

utf8 varchar(n)里一个字符包含3个字节,总字节为3*n+2;

utf8mb4 char(n)里一个字符包含4个字节,总字节为4*n;

utf8mb4 varchar(n)里一个字符包含4个字节,总字节为4*n+2;

/*DDL 信息*/------------
CREATE TABLE `actor` (
  `actor_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
  `first_name` varchar(45) NOT NULL,
  `last_name` varchar(45) NOT NULL,
  `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`actor_id`),
  KEY `idx_actor_last_name` (`last_name`)
) ENGINE=InnoDB AUTO_INCREMENT=205 DEFAULT CHARSET=utf8mb4
   id  select_type  table   type    possible_keys  key                  key_len  ref       rows  Extra        
------  -----------  ------  ------  -------------  -------------------  -------  ------  ------  -------------
     1  SIMPLE       actor   index   (NULL)         idx_actor_last_name  182      (NULL)     204  Using index  
     -- 字符集为utf8mb4,每个字符可以包含4个字节。key_len 182=4*45+2
  • ref : 显示哪一列被使用了,或者哪些列和哪些常量用于查找索引。
  • rows : 根据表信息统计以及索引的使用情况,大致估算说要找到所需记录需要读取的行数,rows 越小越好。
  • extra : 包含不适合在其他列显示但很重要的信息。
using filesort说明mysql会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取。mysql中无法利用索引完成的排序操作,成为’文件排序’。尽快优化!
using temporary使用了临时表保存中间结果,mysql在对结果排序时使用临时表,常见于排序order by和分组查询group by。临时表大大降低了系统性能。
using index表示相应的查询操作使用了覆盖索引,避免了回表。如果同时出现了using where,表示索引用来进行索引值的查找;没有出现using where则表示只用来读取数据,而不是用去查询
using where索引用来进行索引值的查找
using join buffer使用了连接缓存
impossible wherewhere字句的值总是false,不能用来获取任何元组
select tables optimized away在没有 GROUPBY 子句的情况下,基于索引优化 MIN/MAX 操作或者 对于 MyISAM 存储引擎优化 COUNT(*)操作,不必等到执行阶段再进行计算, 查询执行计划生成的阶段即完成优化。
distinct优化 distinct,在找到第一匹配的元组后即停止找同样值的工作
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值