欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

三、mysql优化技术-执行计划

程序员文章站 2022-05-07 12:10:37
...

解决问题的一般思路是:发现问题,找到问题的原因,根据原因因地制宜解决。定位到了执行慢的sql语句后,接下来就要分析语句为什么执行慢。

mysql服务器执行sql语句是一个复杂的过程,大致流程如下:

1、接收客户端发送的sql语句;
2、对于查询语句,服务器先检查查询缓存,如果命中了缓存,则立刻返回存储在缓存中的结果,否则进入下一阶段;
3、进行SQL解析、预处理,在优化器生成对应的执行计划;
4、mysql根据优化器生成的执行计划,调用存储引擎的API来执行查询;
5、将结果返回给客户端。

也就是说,mysql服务器不是直接执行我们写的sql语句的,而是要对其进行优化,那如果能知道一些mysql优化的细节,对于我们寻找原因有很大帮助,mysql提供了查看执行计划的命令explain关键字,使用方法就是在执行的sql前加explain关键字,explain sql。

我们来看一条sql的执行:
三、mysql优化技术-执行计划
            
    
    博客分类: mysqlmysql优化 mysql优化执行计划 
 这条sql执行了4秒多,表结构如下:
三、mysql优化技术-执行计划
            
    
    博客分类: mysqlmysql优化 mysql优化执行计划 

表中总记录数如下:
三、mysql优化技术-执行计划
            
    
    博客分类: mysqlmysql优化 mysql优化执行计划 
 

查看一下这条sql语句的执行计划:
三、mysql优化技术-执行计划
            
    
    博客分类: mysqlmysql优化 mysql优化执行计划 
 

下表是个字段含义解释


字段
说明
可选值
id
查询序列号,表示查询中执行select子句或操作表的顺序
id相同,执行顺序由上至下,如果是子查询,id的序号会递增,
id值越大优先级越高,越先被执行  
一组数字
select_type
查询中每个select子句的类型 

SIMPLE:简单SELECT(不使用UNION或子查询)  

PRIMARY:包含复杂子部分时最外层查询

UNION:UNION中的第二个或后面的SELECT语句

DEPENDENT UNION:UNION中的第二个或后面的SELECT语句,取决于外面的查询

UNION RESULT:从UNION表获取结果的SELECT

SUBQUERY:SELECT或WHERE列表中的子查询的第一个SELECT

DEPENDENT SUBQUERY:子查询中的第一个SELECT,取决于外面的查询

DERIVED:FROM子句的子查询中包含UNION,外层SELECT

SIMPLE
PRIMARY
UNION

DEPENDENT UNION

UNION RESULT

SUBQUERY

DEPENDENT SUBQUERY

DERIVED

table

输出的行所引用的表

表名

type

联接类型,在表中找到所需行的方式

system:查询的表仅有一行数据

const:表最多有一个匹配行,如根据主键查询,或查询列有unique约束

eq_ref:对于每个来自于前面的表的行组合,从该表中读取一行,它用在一个索引的所有

部分被联接使用并且索引是UNIQUEPRIMARY KEY

ref:非唯一性索引扫描,返回匹配某个单独值的所有行。常见于使用非唯一索引或

唯一索引的非唯一前缀进行的查找

ref_or_null:ref,但是添加了MySQL可以专门搜索包含NULL值的行

index_merge:使用索引合并优化方法

unique_subquery:索引查找函数,可以完全替换子查询,效率更高

index_subquery:类似于unique_subquery,可以替换IN子查询

range:只检索给定范围的行,使用一个索引来选择行,key列显示使用了哪个索引

index:ALL相同,除了只有索引树被扫描,通常比ALL

ALL:全表扫描,遍历全表以找到匹配的行

从上至下,性能由高到低

system

const

eq_ref

ref

ref_or_null

index_merge

unique_subquery

index_subquery

range

index

ALL

possible_keys

指出MySQL能使用哪个索引在表中找到行,查询涉及到的字段上若存在索引,
则该索引将被列出,但不一定被查询使用 ,如果该列是NULL,则没有相关的索引
 

key

显示实际使用的索引,若没有使用索引,显示为NULL,
要想强制MySQL使用或忽视possible_keys中的索引,在查询中使用
FORCE INDEXUSE INDEX或者IGNORE INDEX 
 

key_len

显示mysql决定使用的键长度(字节数 )

 

ref

显示使用哪个列或常数与key一起从表中选择行

 

rows

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

Extra

包含MySQL解决查询的详细信息
Distinct:发现第1个匹配行后,停止搜索更多的行
Not exists:对查询进行LEFT JOIN优化,发现1个匹配LEFT JOIN标准的行后,不再为
前面的的行组合在该表内检查更多的行
Using filesort:无法利用索引完成的排序操作
Using index:表示相应的select操作中使用了覆盖索引,MySQL可以利用索引返回select
列表中的字段,而不必根据索引再次读取数据文件,包含所有满足查询需要的数据的
索引称为覆盖索引
Using temporary:表示MySQL需要使用临时表来存储结果集,常见于排序和分组查询
Using where:使用where子句来过滤结果集

Distinct

Not exists

Using filesort

Using index

Using temporary

Using where

 回过头来看下之前的查询计划,这是一个对emp表的简单查询,没有使用索引,扫描全表,并使用where条件过滤结果集,查询到结果可能要扫描400万行记录。
已经找到了导致sql执行慢的一些地方,接下来就能有针对性的优化了。
 
 
 
  • 三、mysql优化技术-执行计划
            
    
    博客分类: mysqlmysql优化 mysql优化执行计划 
  • 大小: 2.9 KB
  • 三、mysql优化技术-执行计划
            
    
    博客分类: mysqlmysql优化 mysql优化执行计划 
  • 大小: 4.9 KB
  • 三、mysql优化技术-执行计划
            
    
    博客分类: mysqlmysql优化 mysql优化执行计划 
  • 大小: 1.5 KB
  • 三、mysql优化技术-执行计划
            
    
    博客分类: mysqlmysql优化 mysql优化执行计划 
  • 大小: 5.7 KB