首页 > 数据库 >MySQL 优化篇(二)

MySQL 优化篇(二)

时间:2022-09-18 22:57:44浏览次数:85  
标签:语句 type 查询 索引 MySQL NULL 优化 SELECT

分析查询语句:EXPLAIN

定位了查询慢的SQL之后,我们就可以使用EXPLAIN或DESCRIBE工具做针对性的分析查询语句。DESCRIBE 语句的使用方法与EXPLAIN语句是一样的,并且 分析结果也是一样的。

MySQL中有专门负责优化SELECT语句的优化器模块,主要功能:通过计算分析系统中收集到的统计信息,为客户端请求的Quy提供它认为最优的执行计划(他认为最优的数据检索方式,但不见得是DB认为是最优的,这部分最耗费时间)

这个执行计划展示了接下来具体执行查询的方式,比如多表连接的顺序是什么,对于每个表采用什么访问方法来具体执行查询等等。MySQL 为我们提供了 EXPLAIN 语句来帮助我们查看某个查询语句的具体执行计划,大家看懂 EXPLAIN 语句的各个输出项,可以有针对性的提升我们查询语句的性能。

基本语法

EXPLAIN 或 DESCRIBE 语句的语法形式如下:

EXPLAIN SELECT select_options;
或者
DESCRIBE SELECT select_options;

如果我们想看看某个查询的执行计划的话,可以在具体的查询语句前边加一个 EXPLAIN

mysql> explain select 1;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra          |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------+
|  1 | SIMPLE      | NULL  | NULL       | NULL | NULL          | NULL | NULL    | NULL | NULL |     NULL | No tables used |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------+
1 row in set, 1 warning (0.00 sec)

EXPLAIN 语句输出的各个列的作用如下:

列名 描述
id 在一个大的查询语句中每个SELECT关键字都对应一个 唯一的id
id 如果相同,可以认为是一组,从上往下顺序执行;
在所有组中,id 值越大,优先级越高,越先执行
select_type SELECT关键字对应的那个查询的类型
table 表名
partitions 匹配的分区信息,非分区表,该项为 NULL。一般情况下我们的查询语句的执行计划的 partitions 列的值都是 NULL。
type 支队单表的访问方法
possible_type 可能用到的索引
key 实际上使用的索引
key_len 实际使用到的索引长度
ref 当使用索引列等值查询时,与索引列进行等值匹配的对象信息
rows 预估的需要读取的记录条数,值越小越好
filtered 某个表经过搜索条件过滤后剩余记录条数的百分比
Extra 一些额外的信息

重要字段解析

select_type

一条大的查询语句里边可以包含若干个 SELECT 关键字,每个 SELECT 关键字代表着一个小的查询语句,而每个 SELECT:关键字的 FROM 子句中都可以包含若干张表(这些表用来做连接查询),每一张表都对应着执行计划输出中的一条记录,对于在同一个 SELECT 关键字中的表来说,它们的 id 值是相同的。

MySQL 为每一个 SELECT 关键字代表的小查询都定义了一个称之为 select_type 的属性,意思是我们只要知道了某个小查询的 select_type 属性,就知道了这个小查询在整个大查询中扮演了一个什么角色,我们看一下 select_type 都能取哪些值,请看官方文档:

名称 描述
SIMPLE Simple SELECT(not using UNION or subqueries)
简单 SELECT(不使用 UNION 或子查询)
PRIMAPY Outermost SELECT
最外层选择
UNION Second or later SELECT statement in a UNION
UNION 中的第二个或以后的 SELECT 语句
UNION RESULT Result of a UNION
UNION 的结果
SUBQUERY First SELECT in subquery
子查询中的第一个 SELECT
DEPENDENT SUBQUERY First SELECT in subquery,dependent on outer query
子查询中的第一个 SELECT,依赖于外部查询
DERIVED Derived table
派生表
MATERIALIZED Materialized subquery
物化子查询
UNCACHEABLE SUBQUERY A subquery for which the result cannot be cached and must be re-evaluated for each row of the outer query
一个子查询,其结果无法缓存,必须为外部查询的每一行重新计算
UNCACHEABLE UNION The second or later select in a UNION that belongs to an uncacheable subquery (see UNCACHEABLE SUBQUERY)
属于不可缓存子查询的 UNION 中的第二个或更晚选择(请参阅 UNCACHEABLE SUBQUERY)

type

执行计划的一条记录就代表着 MySQL 对某个表的执行查询时的访问方法,又称“访问类型",其中的 type 列就表明了这个访问方法是啥,是较为重要的一个指标。比如,看到 type 列的值是ref,表明 MySQL 即将使用 ref 访问方法来执行对 s1 表的查询。

完整的访问方法如下:systemconsteq_refreffulltextref_or_nullindex_merge unique_subqueryindex_subqueryrangeindexALL

  • system

    当表中只有一条记录并且该表使用的存储引擎的统计数据是精确的,比如 MyISAM,Memory。那么对该表的访问方法就是system

  • const

    当我们根据主键或者唯一二级索引列与常数进行等值匹配时,对单表的访问方法就是cost;

    示例是根据 employees 表中的主键进行查询:

    image

  • eq_ref

    在连接查询时,如果被驱动表是通过主键或者唯一二级索引列等值匹配的方式进行访问的(如果该主键或者唯一二级索引是联合索引的话,所有的索引列都必须进行等值比较),则对该被驱动表的访问方法就是 eq_ref

    image

  • ref

    当通过普通的二级索引列与常量进行等值匹配来查询某个表时,那么对该表的访问方法就可能是ref

    image

  • ref_or_null

    当对普通二级索引进行等值匹配查询,该索引列的值也可以是 NULL 值时,那么对该表的访问方法就可能是ref_or_null

  • index_merge

    单表访问方法时在某些场景下可以使用IntersectionUnionsort-Union 这三种索引合并的方式米执行查询

    image

  • unique_subquery

    unique_subquery 是针对在一些包含 IN 子查询的查询语句中,如果查询优化器决定将 IN 子查询转换为 EXISTS 子查询,而且子查询可以使用到主键进行等值匹配的话,那么该子查询执行计划的type列的值就是unique_subquery

  • range

    如果使用索引获取某些~范围区间`的记录,那么就可能使用到`range`访问方法

    image

  • index

    当我们可以使用索引覆盖,但需要扫描全部的索引记录时,该表的访问方法就是index

  • ALL

    全表扫描

    image

possible_key 与 key

可供选择的索引与实际用到的索引

在 EXPLAIN 语句输出的执行计划中,possible_keys 列表示在某个查询语句中,对某个表执行单表查询时可能用到的索引有哪些。一般查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询使用。key 列表示实际用到的索引有哪些,如果为 NULL 则没有使用索引。

key_len

实际使用到的索引长度(即:字节数),检查是否充分的利用上索引。对于联合索引来说:值越大越好。说明充分利用到了索引。

计算规则示例:
  • varchar(10):变长字段且允许 NULL = 10 * (character set:utf8=3,gbk=2,latinl=1) + 1 (NULL) + 2 (变长字段)
  • varchar(10):变长字段且不允许 NULL = 10 * (character set:utf8=3,gbk=2,latinl=1 ) + 2 ( 变长字段 )
  • char(10):固定字段且允许NULL = 10 (character set:utf8=3,gbk=2,latinl=1) + 1(NULL)
  • char(10):固定字段且不允许NULL = 10 (character set:utf8=3,gbk=2,latinl=1)

filtered

某个表经过搜索条件过滤后剩余记录条数的百分比。

如果使用的是索引执行的单表扫描,那么计算时需要估计出满足除使用到对应索引的搜索条件外的其他搜索条件的记录有多少条。

image

对于单表查询来说,这个filtered列的值没什么意义,我们更关注在连接查询中驱动表对应的执行计划记录的filtered值,它决定了被驱动表要执行的次数(即:rows * filtered)

image

Extra

Extra 列是用来说明一些额外信息的,包含不适合在其他列中显示但十分重要的额外信息。我们可以通过这些额外信息来更准确的理解MySQL到底将如何执行给定的查询语句。MySQL提供的额外信息有好几十个,只挑比较重要的额外信息介绍。

  • No tables used

    当查询语句没有 FROM 子句时会提示该额外信息,比如:

    image

  • Impossible WHERE

    查询语句的 WHERE 子句水远为FALSE 时将会提示该额外信息:

    image

  • Using where

    当我们使用全表扫描来执行对某个表的查询,并且该语句的 WHERE 子句中有针对该表的搜索条件时,在Extra列中会提示上述额外信息。

    当使用索引访问米执行对某个表的查询,并且该语句的 WHERE 子句中有除了该索引包含的列之外的其他搜索条件时,在Extra列中也会提示上述额外信息。

    image

  • No matching min/max row

    当查询列表处有MIN或者 MAX 聚合函数,但是并没有符合WHERE子句中的搜索条件的记录时,将会提示该额外信息。

    image

  • Using index

    当我们的查询列表以及搜索条件中只包含属于某个索引的列,也就是在可使用覆盖索引的情况下,在Extra列将会提示该额外信息。比如说下边这个查询中只需要用到索引而不需要回表操作:

    image

  • Using index condition

    搜索条件里面出现了索引列,但是却不能使用索引:

    image

  • join buffer

    在连接查询执行过程中,当被驱动表不能有效的利用索引加快访问速度,MySQL一般会为其分配一块名叫join buffer内存块来加快查询速度,也就是我们所讲的基于块的嵌套循环算法:

    image

  • Not exists

    当我们使用左(外)连接时,如果WHEE子句中包含要求被驱动表的某个列等于NULL值的搜索条件,而且那个列又是不允许存储NULL值的,那么在该表的执行计划的Extra列就会提示Not exists额外信息:

    image

标签:语句,type,查询,索引,MySQL,NULL,优化,SELECT
From: https://www.cnblogs.com/lhnstart/p/16706140.html

相关文章

  • Mysql 安全加固经验总结
    本文为博主原创,转载请注明出处:目录1.内网部署Mysql2.使用独立用户运行msyql3.为不同业务创建不同的用户,并设置不同的密钥4.指定mysql可访问用户ip......
  • MySQL:互联网公司常用分库分表方案汇总!
    一、数据库瓶颈不管是IO瓶颈,还是CPU瓶颈,最终都会导致数据库的活跃连接数增加,进而逼近甚至达到数据库可承载活跃连接数的阈值。在业务Service来看就是,可用数据库连接少甚至......
  • MySQL列转行、行转列
    1795.每个产品在不同商店的价格列转行SELECTproduct_id,'store1'store,store1priceFROMproductsWHEREstore1ISNOTNULLUNIONSELECTproduct_id,'store2......
  • 配置MySQL的tab补全方法
    方法一####安装相关依赖软件(需要配置yum官方或者阿里源进行安装)```1yum-yinstallepel-release2yum-yinstallzlib-develbzip2-developenssl-develncurses......
  • MySQL基础架构:SQL查询语句执行过程
    MySQL是一种关系型数据库管理系统,采用的是分层结构,本文中将简单介绍MySQL数据库的内部架构。目录客户端层服务器层连接器查询缓存分析器优化器执行器存储层MySQL是一个C/......
  • Pymysql增删改查
    1、mysqlDDL(数据定义语言)、DML(数据操作语言)和DCL(数据控制语言)查看服务器版本selectversion();查看所有数据库。showdatabases;切换到指定数据库。usemysql;......
  • MySQL学习——DML操作(添加,更新,删除数据)
    本章将介绍MySQL中的DML操作1、添加数据(INSERT)1.1、插入语法结构:INSERTINTO表名(column1,column2,...)VALUES(value1,value2,....)上述插入是指定列......
  • linux mysql数据 解决ERROR 1045 (28000): Access denied for user 'root'@'localhost
    在linux系统是输入命令: mysql-uroot-p输入密码后 提示 ERROR1045(28000):Accessdeniedforuser'root'@'localhost'(usingpassword:YES):说明输入的密码是......
  • 【Mysql】事务的基本特性和隔离级别
    事务的基本特性ACID分别是:原子性(atomicity)指的是一个事务中的操作要么都成功,要么都失败。一致性(consistency)指的是数据库总是从一个一致性状态转移到另外一个一致性状态。......
  • MySQL的日志模块
    一、redologMySQL里经常说到的WAL技术,WAL的全称是Write-AheadLogging,它的关键点就是先写日志,再写磁盘。(“先写日志”也是先写磁盘,只是写日志是顺序写盘,速度很快......