Mysql优化(出自官方文档) - 第十一篇(查询计划篇)

1 EXPLAIN Output Format

由于EXPLAIN的内容较多,所以这里只会摘录一些重要的地方,详情可以参考原文。

EXPLAIN的结果解释:

Column JSON Name Meaning
id select_id The SELECT identifier
select_type None The SELECT type
table table_name The table for the output row
partitions partitions The matching partitions
type access_type The join type
possible_keys possible_keys The possible indexes to choose
key key The index actually chosen
key_len key_length The length of the chosen key
ref ref The columns compared to the index
rows rows Estimate of rows to be examined
filtered filtered Percentage of rows filtered by table condition
Extra None Additional information

摘一些重要的列:

  • table

    即表名,但是也有可能是下面三种情况。

    • <union*M*,*N*>:表示多个表的union,其中M和N分别为第一列的id
    • <derived*N*>:表示来自于其他表的衍生表,同上,M和N表示第一列的id,通常,衍生表来自于from语句后面的select
    • <subquery*N*>: 表示物化后的子查询,N为第一列的id。
  • partitions

    对于有分区的表该列有效

  • type

    即join type,分别有常见的system``, const, eq_ref, ALL等, 下一节将详细介绍。

  • possible_keys

    表示待选的索引

  • key

    表示实际上用到的索引,来自于possible_keys,当possible_keys不为NULL的时候,该列也有可能为none,因为有时候用索引的效率不定义会比扫表高。

  • key_len

    Mysql决定使用索引的长度(哪些部分),当一列有可能为NULL的时候,key_len的长度可能比该列大。

  • ref

    表示用来和索引比较的常量或者某一列。

  • rows, filtered

    rows表示Mysql预估将要扫描的行数,filtered表示Mysql预估的能过滤的行数(这里值的是返回给用户的行数),比如rows为100, filtered为70%,那么Mysql预估返回给用户70行数据。

  • Extra

    表示Mysql解析一个query的一些额外信息,比如Using Index,Using filesort等等。

EXPLAIN Join Types

对于type列,经常用于join的场景,下面将根据效率由高到低进行说明:

  • system

    const的一种特殊情况,表示该表只有一行数据

  • const

    表示只有最多只有一行匹配的数据,虽然该表可能有多行数据,但是对于和其join的表,其只需要一行数据,可以视作为const,经常用于primary key或者unique key中,比如下面的语句:

    SELECT * FROM tbl_name WHERE primary_key=1;
    
    SELECT * FROM tbl_name
    WHERE primary_key_part1=1 AND primary_key_part2=2;
  • eq_ref

    Mysql可以使用索引进行equal操作,只适用于equal的情况,并且索引类型必须为primary key或者unique not null,在join的时候,这是除了system和const最好的情况。

  • ref

    当一个索引不是primary key或者unique index的时候,又或者只能使用leftmost的时候,就会使用到ref的情况,适用于=或者<=>

  • fulltext

  • ref_or_null

    和ref很像,但是除此之外,还需要额外寻找null字段,经常用于一些子查询的情况,比如下面的语句:

    SELECT * FROM ref_table
    WHERE key_column=expr OR key_column IS NULL;
  • index_merge

    表示会使用Section 8.2.1.3, “Index Merge Optimization”.技术进行优化

  • unique_subquery

    和eq_ref等价的情况,不过是针对于子查询的,譬如下面的语句:

    value IN (SELECT primary_key FROM single_table WHERE some_expr)
  • index_subquery

    和unique_subquery很像,不过是针对于子查询中的nonunique index的,譬如下面的语句:

    value IN (SELECT key_column FROM single_table WHERE some_expr)
  • range

    一般索引的范围查找会用到,该种情况下,key列表示所使用的索引,key_len表示所使用的最长的key part,ref是NULL,适用于索引列和一个常量进行对比的情况,包括:=, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, LIKE, 或者IN,譬如下面的语句:

    SELECT * FROM tbl_name
    WHERE key_column = 10; SELECT * FROM tbl_name
    WHERE key_column BETWEEN 10 and 20; SELECT * FROM tbl_name
    WHERE key_column IN (10,20,30); SELECT * FROM tbl_name
    WHERE key_part1 = 10 AND key_part2 IN (10,20,30);
  • index

    类似于ALL,不过这种情况下是索引扫描,通常情况下,Extra列为Using Index

  • ALL

    最糟糕的情况,这种情况下只能进行全表扫描,此时应该考虑创建索引来加快join的速度。

EXPLAIN Extra Information

该小节省略,因为Extra列的信息都比较易懂,碰到不清楚的可参考这里。

2 Extended EXPLAIN Output Format

在EXPLAIN之后,执行SHOW WARNINGS命令,会看到EXPLAIN的一些附加信息,在8.0.12之后,该附加信息的适用条件为:SELECT, DELETE, INSERT, REPLACE和UPDATE,在8.0.12之前,该附加信息只有在SELECT语句下才会产生,看下面的一个例子:

mysql> EXPLAIN
SELECT t1.a, t1.a IN (SELECT t2.a FROM t2) FROM t1\G
*************************** 1. row ***************************
id: 1
select_type: PRIMARY
table: t1
type: index
possible_keys: NULL
key: PRIMARY
key_len: 4
ref: NULL
rows: 4
filtered: 100.00
Extra: Using index
*************************** 2. row ***************************
id: 2
select_type: SUBQUERY
table: t2
type: index
possible_keys: a
key: a
key_len: 5
ref: NULL
rows: 3
filtered: 100.00
Extra: Using index
2 rows in set, 1 warning (0.00 sec) mysql> SHOW WARNINGS\G
*************************** 1. row ***************************
Level: Note
Code: 1003
Message: /* select#1 */ select `test`.`t1`.`a` AS `a`,
<in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in
( <materialize> (/* select#2 */ select `test`.`t2`.`a`
from `test`.`t2` where 1 having 1 ),
<primary_index_lookup>(`test`.`t1`.`a` in
<temporary table> on <auto_key>
where ((`test`.`t1`.`a` = `materialized-subquery`.`a`))))) AS `t1.a
IN (SELECT t2.a FROM t2)` from `test`.`t1`
1 row in set (0.00 sec)

注意,可以看到这些查询语句可能会被重写,且包含特殊的标记符,所以这些语句不一定是合法的SQL语句,该语句只是为了表示Mysql是如何具体来解析和执行的。

对于这些特殊的标记,部分解释如下:

  • <auto_key>

    为临时自动生成的key

  • (expr)

    表示该语句会被缓存在内存中,以后可能会使用到。

  • (query fragment)

    表示语句被重写成了EXISTS

    等等,还有很多,这里就不一一介绍了。

3 Extended EXPLAIN Output Format

EXPLAIN FOR CONNECTION语句用于一些性能诊断的情况,比如:一个session执行的时间很长,那么可以在另外一个session中使用该命令,指定特定的connection id,那么就可以看到之所以执行这么长时间的额原因,该命令的格式如下:

EXPLAIN [options] FOR CONNECTION connection_id;

该命令适用于 SELECT, DELETE, INSERT, REPLACE, and UPDATE. 但是,该命令不适用于任何prepared语句。

connection_id是一个conection的标识符,该id可从 INFORMATION_SCHEMA PROCESSLIST table or the SHOW PROCESSLIST statement中获取,但是使用者必须要有相关的权限,否则无法获取。

mysql的优化_第十一篇(查询计划篇)的更多相关文章

  1. mysql系列八、mysql数据库优化、慢查询优化、执行计划分析

    mysql的性能优化无法一蹴而就,必须一步一步慢慢来,从各个方面进行优化,最终性能就会有大的提升. 一.介绍 对mysql优化是一个综合性的技术,主要包括 表的设计合理化(符合3NF) 添加适当索引( ...

  2. MySQL分页优化_别再用offset和limit分页了

    终于要对MySQL优化下手了,本文将对分页进行优化说明,希望可以得到一个合适你的方案. 开始之前,先分享一套MySQL教程,小白入门或者学习巩固都可以看 MySQL基础入门-mysql教程-数据库实战 ...

  3. MySQL SQL优化之in与range查询【转】

    本文来自:http://myrock.github.io/ 首先我们来说下in()这种方式的查询.在<高性能MySQL>里面提及用in这种方式可以有效的替代一定的range查询,提升查询效 ...

  4. mysql数据库优化方法大数据量查询轻松解决

    1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...

  5. mysql监控优化(三)慢查询

    顾名思义,慢查询日志中记录的是执行时间较长的query,也就是我们常说的slowquery,通过设--log-slow-queries[=file_name]来打开该功能并设置记录位置和文件名.慢查询 ...

  6. MySQL数据库优化_索引

    1.添加索引后减少查询需要的行数,提高查询性能 (1) 建表 CREATE TABLE `site_user` ( `id` ) NOT NULL AUTO_INCREMENT COMMENT '自增 ...

  7. MySQL架构优化实战系列3:定时计划任务与表分区

    原创 2016-07-08 汤抗 DBAplus社群 一 定时计划任务 1.概论   mysql计划任务可以定时更新数据库表或者做大文件的汇总表.   2.配置 开启计划任务 SHOW VARIABL ...

  8. MySQL架构优化:定时计划任务与表分区

    转自: MySQL架构优化实战系列3:定时计划任务与表分区 - 今日头条(TouTiao.com)http://toutiao.com/a6304736482361049345/?tt_from=mo ...

  9. Mysql优化_第十三篇(HashJoin篇)

    Mysql优化_第十三篇(HashJoin篇) 目录 Mysql优化_第十三篇(HashJoin篇) 1 适用场景 纯等值查询,不能使用索引 等值查询,使用到索引 多个join条件中至少包含一个等值查 ...

随机推荐

  1. k3d入门指南:在Docker中运行K3s

    在本文中,我们将简单了解k3d,这是一款可让您在安装了Docker的任何地方运行一次性Kubernetes集群的工具,此外在本文中我们还将探讨在使用k3d中可能会出现的一切问题. 什么是k3d? k3 ...

  2. File & Directory

    新开一节IO(Input/Output)的用法. 这节主要讲一下操作文件和文件目录的两个静态类:File 和 Directory. 在进入正题之前,先理解一下相对路径和绝对路径这两个概念: 绝对路径, ...

  3. JS数组的操作方法汇总

    数组的增删 push():添加到最后 pop():取出最后一个 shift():取出第一个 unshift():添加到第一个 splice() : 返回删除的数组,如果没有则为空数组,会改变原数组.可 ...

  4. [项目] 淘淘商城 Part.2

    商品列表查询 Easyui 商品添加 商品类目选择 图片上传 富文本编辑器使用 添加的实现 展示首页 略 分页插件 在SqlMapConfig.xml,配置一个plugin 在sql语句执行之前,添加 ...

  5. [Python] tkinter 之 Listbox & Combobox

    示例: 1 #用户界面 2 import os 3 os.chdir('F:\\spyder_workspace\\ColCal') 4 import Main 5 from tkinter impo ...

  6. Deepin深度应用商店和系统更新不正常的解决方法

    Deepin深度应用商店和系统更新不正常的解决方法 2020-02-04 10:25:09作者:i8520稿源:深度站 如果你的Deepin深度应用商店和系统更新不正常,可采用以下方法来解决问题. 解 ...

  7. Centos7 docker容器启动后添加端口映射

    docker容器启动后添加端口映射的两种方法: 一.通过修改防火墙策略添加端口映射 docker容器已创建好,但是想在容器内配置tomcat监控,需要新的端口去访问,但是映射时没有映射多余端口,此时, ...

  8. stm32中关于NVIC_SetVectorTable函数使用的疑惑与理解

    [转载]2017年12月4日14:48:29 先描述下这几天碰到的一个奇怪的问题: 一个基于stm32的工程中使用到了IAP编程,其中boot空间预留长度为0x6100,实际boot的bin文件大小为 ...

  9. windows server 2008 rdp停止服务 - windows server 2012 R2 远程桌面授权模式尚未配置,远程桌面服务将在120天内停止工作

    目录 问题现象 增长rdp服务可使用时长的配置 Via & reference: 问题现象 windows server 2008作为测试环境跳板机,但是没有配置官方的rdp授权,限制用户登录 ...

  10. ssh创建与添加密钥开启免密登陆 免确认机器指纹参数

     主要是两个步骤 1.控制主机创建密钥对(私钥和公钥) 2.把密钥对的公钥加入对方的认证列表中 [root@vps ~]# ssh-keygen [root@vps ~]# ssh-copy-id u ...