MySQL学习笔记3---Explain字段分析

3、MySQL 逻辑架构简介

3.1、整体架构图

连接层

​ 最上层是一些客户端和连接服务,包含本地 sock 通信和大多数基于客户端/服务端工具实现的类似于 tcp/ip 的通信。主要完成一些类似于连接处理、授权认证、及相关的安全方案。在该层上引入了线程池的概念,为通过认证安全接入的客户端提供线程。同样在该层上可以实现基于 SSL 的安全链接。服务器也会为安全接入的每个客户端验证它所具有的操作权限。

服务层

Management Serveices & Utilities 系统管理和控制工具
SQL Interface SQL 接口。接受用户的 SQL 命令,并且返回用户需要查询的结果。比如 select from就是调用 SQL Interface
Parser 解析器。 SQL 命令传递到解析器的时候会被解析器验证和解析
Optimizer 查询优化器。 SQL 语句在查询之前会使用查询优化器对查询进行优化,比如有where 条件时,优化器来决定先投影还是先过滤。
Cache 和 Buffer 查询缓存。如果查询缓存有命中的查询结果,查询语句就可以直接去查询缓存中取数据。这个缓存机制是由一系列小缓存组成的。比如表缓存,记录缓存,key 缓存,权限缓存等

引擎层

​ 存储引擎层,存储引擎真正的负责了 MySQL 中数据的存储和提取,服务器通过 API 与存储引擎进行通信。不同的存储引擎具有的功能不同,这样我们可以根据自己的实际需要进行选取。

存储层

​ 数据存储层,主要是将数据存储在运行于裸设备的文件系统之上,并完成与存储引擎的交互。

3.2、存储引擎

show engines; —查看所有的数据库引擎

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NFzeXfJ9-1606014166164)(images3/image-20201119200628016.png)]

show variables like ‘%storage_engine%’; —查看默认的数据库引擎

MyISAM 和 InnoDB

对比项 MyISAM InnoDB
外键 不支持 支持
事务 不支持 支持
行表锁 表锁,即使操作一条记录也会锁住整个表,不适合高并发的操作 行锁,操作时只锁某一行,不对其它行有影响,适合高并发的操作
缓存 只缓存索引,不缓存真实数据 不仅缓存索引还要缓存真实数据,对内存要求较高,而且内存大小对性能有决定性的影响
关注点 读性能 并发写、事务、资源
默认使用 N Y

4、索引优化分析

4.1、SQL 执行顺序

  • 手写的顺序:

  • 真正执行的顺序:
    在这里插入图片描述
    在这里插入图片描述

查询流程

  1. mysql 客户端通过协议与 mysql 服务器建连接,发送查询语句,先检查查询缓存,如果命中,直接返回结果,否则进行语句解析,也就是说,在解析查询之前,服务器会先访问查询缓存(query cache)——它存储 SELECT 语句以及相应的查询结果集。如果某个查询结果已经位于缓存中,服务器就不会再对查询进行解析、优化、以及执行。它仅仅将缓存中的结果返回给用户即可,这将大大提高系统的性能。
  2. 语法解析器和预处理:首先 mysql 通过关键字将 SQL 语句进行解析,并生成一颗对应的“解析树”。mysql 解析器将使用 mysql 语法规则验证和解析查询;预处理器则根据一些 mysql 规则进一步检查解析数是否合法。
  3. 查询优化器当解析树被认为是合法的了,并且由优化器将其转化成执行计划。一条查询可以有很多种执行方式,最后都返回相同的结果。优化器的作用就是找到这其中最好的执行计划。
  4. 然后,mysql 默认使用的 BTREE 索引,并且一个大致方向是:无论怎么折腾 sql,至少在目前来说,mysql 最多只用到表中的一个索引。

4.2、常见的 Join 查询

在这里插入图片描述
在这里插入图片描述

1、SELECT * FROM tbl_emp a LEFT JOIN tbl_dept b ON a.deptId=b.id;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mFxsVzpf-1606014166176)(images3/image-20201119212605400.png)]

2、SELECT * FROM tbl_emp a INNER JOIN tbl_dept b ON a.deptId=b.id;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jhZXRd9g-1606014166177)(images3/image-20201119212752445.png)]

3、SELECT * FROM tbl_emp a RIGHT JOIN tbl_dept b ON a.deptId=b.id;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1TnJFRKb-1606014166178)(images3/image-20201119212921678.png)]

4、SELECT * FROM tbl_emp a LEFT JOIN tbl_dept b ON a.deptId=b.id WHERE b.id IS NULL; 

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tr0YbRF8-1606014166179)(images3/image-20201119213208627.png)]

5、SELECT * FROM tbl_emp a RIGHT JOIN tbl_dept b ON a.deptId=b.id WHERE a.deptId IS NULL; 

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2RJgUHMV-1606014166180)(images3/image-20201119213323394.png)]

6SELECT * FROM tbl_emp a LEFT JOIN tbl_dept b ON a.deptId=b.id
    UNION
    SELECT * FROM tbl_emp a RIGHT JOIN tbl_dept b ON a.deptId=b.id;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W7q8Fh1x-1606014166181)(images3/image-20201119213801306.png)]

7SELECT * FROM tbl_emp a LEFT JOIN tbl_dept b ON a.deptId=b.id WHERE b.id IS NULL
UNION
SELECT * FROM tbl_emp a RIGHT JOIN tbl_dept b ON a.deptId=b.id WHERE a.deptId IS NULL; 

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pX7TtUH2-1606014166182)(images3/image-20201119214135956.png)]

4.3、索引的概念

4.3.1、定义

MySQL 官方对索引的定义为:索引(Index)是帮助 MySQL 高效获取数据的数据结构。可以得到索引的本质:索引是数据结构,可以简单理解为排好序的快速查找数据结构

4.3.2、优缺点

优势:

  1. 提高数据检索的效率,降低数据库的IO成本。
  2. 通过索引列对数据进行排序,降低数据排序的成本,降低了CPU的消耗。

缺点:

  1. 虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件每次更新添加了索引列的字段,都会调整因为更新所带来的键值变化后的索引信息。
  2. 实际上索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录,所以索引列也是要占用空间的。

4.4、索引的分类

4.4.1、单值索引

概念: 即一个索引只包含单个列,一个表可以有多个单列索引

1、KEY (customer_name)
2、CREATE INDEX idx_customer_name ON customer(customer_name);

4.4.2、唯一索引

概念: 索引列的值必须唯一,但允许有空值

1、UNIQUE (customer_no)
2、CREATE UNIQUE INDEX idx_customer_no ON customer(customer_no);

4.4.3、主键索引

概念: 设定为主键后数据库会自动建立索引,innodb为聚簇索引

1、PRIMARY KEY(id)
2、ALTER TABLE customer add PRIMARY KEY customer(customer_no);
删除
ALTER TABLE customer drop PRIMARY KEY ;

4.4.4、复合索引

概念: 即一个索引包含多个列

1、KEY (customer_no,customer_name)
2、CREATE INDEX idx_no_name ON customer(customer_no,customer_name);

4.4.5、基本语法

操作 命令
创建 CREATE [UNIQUE ] INDEX [indexName] ON table_name(column))
删除 DROP INDEX [indexName] ON mytable;
查看 SHOW INDEX FROM table_name;
使 用 Alter命令 ALTER TABLE tbl_name ADD PRIMARY KEY (column_list) : 该语句添加一个主键,这意味着索引值必须是唯一的,且不能为 NULL。
ALTER TABLE tbl_name ADD INDEX index_name (column_list): 添加普通索引,索引值可出现多次。
ALTER TABLE tbl_name ADD FULLTEXT index_name (column_list):该语句指定了索引为 FULLTEXT ,用于全文索引。

4.5、索引的创建时机

4.5.1、适合创建索引的情况

  1. 主键自动建立唯一索引;
  2. 频繁作为查询条件的字段应该创建索引;
  3. 查询中与其它表关联的字段,外键关系建立索引;
  4. 单键/组合索引的选择问题, 组合索引性价比更高;
  5. 查询中排序的字段,排序字段若通过索引去访问将大大提高排序速度;
  6. 查询中统计或者分组字段;

4.5.2、不适合创建索引的情况

  1. 表记录太少;
  2. 经常增删改的表或者字段;
  3. Where 条件里用不到的字段不创建索引;
  4. 过滤性不好的不适合建索引;

4.6、Explain 性能分析

4.6.1、概念

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

用法: Explain+SQL 语句。

Explain 执行后返回的信息:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k5gyDDZK-1606014166184)(images3/image-20201120104319023.png)]

4.6.2、各字段解释

1、id

select 查询的序列号,包含一组数字,表示查询中执行 select 子句或操作表的顺序。

①id 相同,执行顺序由上至下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3J1vvWS4-1606014166185)(images3/image-20201120105851573.png)]

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dLS1fPZe-1606014166186)(images3/image-20201120105942766.png)]③有相同也有不同

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OoGECxMJ-1606014166187)(images3/image-20201120105955084.png)]

id 如果相同,可以认为是一组,从上往下顺序执行;在所有组中,id 值越大,优先级越高,越先执行

衍生 = DERIVED,比如就是由id为2的查询结果生成的表

关注点:id 号每个号码,表示一趟独立的查询。一个 sql 的查询趟数越少越好

2、select_type

select_type 代表查询的类型,主要是用于区别普通查询、联合查询、子查询等的复杂查询。

select_type 属性 含义
SIMPLE 简单的 select 查询,查询中不包含子查询或者 UNION
PRIMARY 查询中若包含任何复杂的子部分,最外层查询则被标记为 Primary
DERIVED 在 FROM 列表中包含的子查询被标记为 DERIVED(衍生)MySQL 会递归执行这些子查询, 把结果放在临时表里。
SUBQUERY 在SELECT或WHERE列表中包含了子查询
DEPEDENT SUBQUERY 在SELECT或WHERE列表中包含了子查询,子查询基于外层
UNCACHEABLE SUBQUERY 无法使用缓存的子查询
UNION 若第二个SELECT出现在UNION之后,则被标记为UNION;若UNION包含在FROM子句的子查询中,外层SELECT将被标记为:DERIVED
UNION RESULT 从UNION表获取结果的SELECT

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-76iEvX0A-1606014166188)(images3/image-20201120132424275.png)]

3、table

显示这一行的数据是关于哪张表的

4、type

type 是查询的访问类型。是较为重要的一个指标,结果值从最好到最坏依次是:

system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index >ALL ,一般来说,得保证查询至少达到 range 级别,最好能达到 ref。

主要:system > const > eq_ref > ref > range > index > ALL

1、system

表只有一行记录(等于系统表),这是const类型的特例,平时不会出现,这个也可以忽略不计

2、const

表示通过索引一次就找到了,const 用于比较 primary key 或者 unique 索引。因为只匹配一行数据,所以很快如将主键置于 where 列表中,MySQL 就能将该查询转换为一个常量。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mAIs5Hl8-1606014166189)(images3/image-20201120134904398.png)]

3、eq_ref

唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见于主键或唯一索引扫描。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ko2cqcQb-1606014166190)(images3/image-20201120135048697.png)]

4、ref

非唯一性索引扫描,返回匹配某个单独值的所有行.本质上也是一种索引访问,它返回所有匹配某个单独值的行,然而,它可能会找到多个符合条件的行,所以他应该属于查找和扫描的混合体。

没用索引前:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DQJEY7TZ-1606014166191)(images3/image-20201120135452940.png)]

建立索引后:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WtsiVns7-1606014166192)(images3/image-20201120135506878.png)]

5、range

只检索给定范围的行,使用一个索引来选择行。key 列显示使用了哪个索引一般就是在你的 where 语句中出现了 between、<、>、in 等的查询这种范围扫描索引扫描比全表扫描要好,因为它只需要开始于索引的某一点,而结束语另一点,不用扫描全部索引。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lFx1v1Tq-1606014166194)(images3/image-20201120135623408.png)]

6、index

Full Index Scan,index与ALL区别为index类型只遍历索引树。这通常比ALL快,因为索引文件通常比数据文件小。(也就是说虽然all和index都是读全表,但index是从索引中读取的,而all是从硬盘中读的)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8kfEnRis-1606014166195)(images3/image-20201120135816839.png)]

7、all

Full Table Scan,将遍历全表以找到匹配的行。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CdD1az3T-1606014166196)(images3/image-20201120135848724.png)]

5、possible_keys

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

6、key

  • 实际使用的索引。如果为NULL,则没有使用索引。
  • 查询中若使用了覆盖索引,则索引和查询的select字段重叠

7、key_len

表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度。 key_len 字段能够帮你检查是否充分的利用上了索引。ken_len 越长,说明索引使用的越充分。在不损失精确性的情况下,长度越短越好。

在这里插入图片描述
在这里插入图片描述

如何计算:
①先看索引上字段的类型+长度比如 int=4 ; varchar(20) =20 ; char(20) =20
②如果是 varchar 或者 char 这种字符串字段,视字符集要乘不同的值,比如 utf-8 要乘 3,GBK 要乘 2,
③varchar 这种动态字符串要加 2 个字节
④允许为空的字段要加 1 个字节
第一组:key_len=age 的字节长度+name 的字节长度=4+1 + ( 20*3+2)=5+62=67
第二组:key_len=age 的字节长度=4+1=5

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hwuHofY1-1606014166200)(images3/image-20201120143648130.png)]

8、ref

显示索引的哪一列被使用了,如果可能的话,是一个常数。哪些列或常量被用于查找索引列上的值。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZjW1GTPS-1606014166201)(images3/image-20201120144914033.png)]

9、rows

rows 列显示 MySQL 认为它执行查询时必须检查的行数。越少越好!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zsiZGgJU-1606014166202)(images3/image-20201120145851091.png)]

10、Extra

包含不适合在其他列中显示但十分重要的额外信息

Using filesort

说明 mysql 会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取。MySQL 中无法利用索引完成的排序操作称为“文件排序”。

出现 filesort 的情况:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jNFc06OE-1606014166203)(images3/image-20201120151632024.png)]

优化后,不再出现 filesort 的情况:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hTTqb3hc-1606014166204)(images3/image-20201120151752386.png)]

查询中排序的字段,排序字段若通过索引去访问将大大提高排序速度。

Using temporary

使用了临时表保存中间结果,MySQL 在对查询结果排序时使用临时表。常见于排序 order by 和分组查询 group by。

优化前:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w3ZqnDqW-1606014166205)(images3/image-20201120151925453.png)]

优化后:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jknc70TY-1606014166206)(images3/image-20201120151950182.png)]

Using index

Using index 表示相应的 select 操作中使用了覆盖索引(Covering Index),避免访问了表的数据行,效率不错!如果同时出现 using where,表明索引被用来执行索引键值的查找;如果没有同时出现 using where,表明索引只是用来读取数据而非利用索引执行查找。

Using where:表明使用了 where 过滤。

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

impossible where:where 子句的值总是 false,不能用来获取任何元组。

select tables optimized away:在没有GROUPBY子句的情况下,基于索引优MIN/MAX操作或者对于MyISAM存储引擎优化COUNT(*)操作,不必等到执行阶段再进行计算,查询执行计划生成的阶段即完成优化。

distinct:优化distinct,在找到第一匹配的元组后即停止找同样值的工作。

猜你喜欢

转载自blog.csdn.net/qq_42372017/article/details/109923298
今日推荐