mysql explain ref列_MySQL EXPLAIN详解

mysql explain ref列_MySQL EXPLAIN详解MySQLEXPLAIN详解:http://www.jianshu.com/p/ea3fc71fdc45MySQLEXPLAIN命令是查询性能优化不可缺少的一部分,该文主要讲解explain命令的使用及相关参数说明。EXPLAINOutputColumns列名说明id执行编号,标识select所属的行。如果在语句中没子查询或关联查询,只有唯一的select,每行都将显示1。否则,内…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

MySQL EXPLAIN详解:http://www.jianshu.com/p/ea3fc71fdc45

MySQL EXPLAIN命令是查询性能优化不可缺少的一部分,该文主要讲解explain命令的使用及相关参数说明。

EXPLAIN Output Columns

列名 说明

id 执行编号,标识select所属的行。如果在语句中没子查询或关联查询,只有唯一的select,每行都将显示1。否则,内层的select语句一般会顺序编号,对应于其在原始语句中的位置

select_type 显示本行是简单或复杂select。如果查询有任何复杂的子查询,则最外层标记为PRIMARY(DERIVED、UNION、UNION RESUlT)

table 访问引用哪个表(引用某个查询,如“derived3”)

type 数据访问/读取操作类型(ALL、index、range、ref、eq_ref、const/system、NULL)

possible_keys 揭示哪一些索引可能有利于高效的查找

key 显示mysql决定采用哪个索引来优化查询

key_len 显示mysql在索引里使用的字节数

ref 显示了之前的表在key列记录的索引中查找值所用的列或常量

rows 为了找到所需的行而需要读取的行数,估算值,不精确。通过把所有rows列值相乘,可粗略估算整个查询会检查的行数

Extra 额外信息,如using index、filesort等

id

id是用来顺序标识整个查询中SELELCT 语句的,在嵌套查询中id越大的语句越先执行。该值可能为NULL,如果这一行用来说明的是其他行的联合结果。

select_type

表示查询的类型

类型 说明

simple 简单子查询,不包含子查询和union

primary 包含union或者子查询,最外层的部分标记为primary

subquery 一般子查询中的子查询被标记为subquery,也就是位于select列表中的查询

derived 派生表——该临时表是从子查询派生出来的,位于form中的子查询

union 位于union中第二个及其以后的子查询被标记为union,第一个就被标记为primary如果是union位于from中则标记为derived

union result 用来从匿名临时表里检索结果的select被标记为union result

dependent union 顾名思义,首先需要满足UNION的条件,及UNION中第二个以及后面的SELECT语句,同时该语句依赖外部的查询

subquery 子查询中第一个SELECT语句

dependent subquery 和DEPENDENT UNION相对UNION一样

table

对应行正在访问哪一个表,表名或者别名

关联优化器会为查询选择关联顺序,左侧深度优先

当from中有子查询的时候,表名是derivedN的形式,N指向子查询,也就是explain结果中的下一列

当有union result的时候,表名是union 1,2等的形式,1,2表示参与union的query id

注意:MySQL对待这些表和普通表一样,但是这些“临时表”是没有任何索引的。

type

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

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

类型 说明

All 最坏的情况,全表扫描

index 和全表扫描一样。只是扫描表的时候按照索引次序进行而不是行。主要优点就是避免了排序, 但是开销仍然非常大。如在Extra列看到Using index,说明正在使用覆盖索引,只扫描索引的数据,它比按索引次序全表扫描的开销要小很多

range 范围扫描,一个有限制的索引扫描。key 列显示使用了哪个索引。当使用=、 <>、>、>=、、BETWEEN 或者 IN 操作符,用常量比较关键字列时,可以使用 range

ref 一种索引访问,它返回所有匹配某个单个值的行。此类索引访问只有当使用非唯一性索引或唯一性索引非唯一性前缀时才会发生。这个类型跟eq_ref不同的是,它用在关联操作只使用了索引的最左前缀,或者索引不是UNIQUE和PRIMARY KEY。ref可以用于使用=或<=>操作符的带索引的列。

eq_ref 最多只返回一条符合条件的记录。使用唯一性索引或主键查找时会发生 (高效)

const 当确定最多只会有一行匹配的时候,MySQL优化器会在查询前读取它而且只读取一次,因此非常快。当主键放入where子句时,mysql把这个查询转为一个常量(高效)

system 这是const连接类型的一种特例,表仅有一行满足条件。

Null 意味说mysql能在优化阶段分解查询语句,在执行阶段甚至用不到访问表或索引(高效)

possible_keys

显示查询使用了哪些索引,表示该索引可以进行高效地查找,但是列出来的索引对于后续优化过程可能是没有用的

key

key列显示MySQL实际决定使用的键(索引)。如果没有选择索引,键是NULL。要想强制MySQL使用或忽视possible_keys列中的索引,在查询中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。

key_len

key_len列显示MySQL决定使用的键长度。如果键是NULL,则长度为NULL。使用的索引的长度。在不损失精确性的情况下,长度越短越好 。

ref

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

rows

rows列显示MySQL认为它执行查询时必须检查的行数。注意这是一个预估值。

Extra

Extra是EXPLAIN输出中另外一个很重要的列,该列显示MySQL在查询过程中的一些详细信息,MySQL查询优化器执行查询的过程中对查询计划的重要补充信息。

类型 说明

Using filesort MySQL有两种方式可以生成有序的结果,通过排序操作或者使用索引,当Extra中出现了Using filesort 说明MySQL使用了后者,但注意虽然叫filesort但并不是说明就是用了文件来进行排序,只要可能排序都是在内存里完成的。大部分情况下利用索引排序更快,所以一般这时也要考虑优化查询了。使用文件完成排序操作,这是可能是ordery by,group by语句的结果,这可能是一个CPU密集型的过程,可以通过选择合适的索引来改进性能,用索引来为查询结果排序。

Using temporary 用临时表保存中间结果,常用于GROUP BY 和 ORDER BY操作中,一般看到它说明查询需要优化了,就算避免不了临时表的使用也要尽量避免硬盘临时表的使用。

Not exists MYSQL优化了LEFT JOIN,一旦它找到了匹配LEFT JOIN标准的行, 就不再搜索了。

Using index 说明查询是覆盖了索引的,不需要读取数据文件,从索引树(索引文件)中即可获得信息。如果同时出现using where,表明索引被用来执行索引键值的查找,没有using where,表明索引用来读取数据而非执行查找动作。这是MySQL服务层完成的,但无需再回表查询记录。

Using index condition 这是MySQL 5.6出来的新特性,叫做“索引条件推送”。简单说一点就是MySQL原来在索引上是不能执行如like这样的操作的,但是现在可以了,这样减少了不必要的IO操作,但是只能用在二级索引上。

Using where 使用了WHERE从句来限制哪些行将与下一张表匹配或者是返回给用户。注意:Extra列出现Using where表示MySQL服务器将存储引擎返回服务层以后再应用WHERE条件过滤。

Using join buffer 使用了连接缓存:Block Nested Loop,连接算法是块嵌套循环连接;Batched Key Access,连接算法是批量索引连接

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

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

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

explain的作用

我们使用explain命令来查看mysql语句的执行计划(execution plan),解释mysql是如何执行一条sql语句的;解释的内容主要包括表的连接方式和顺序,以及索引的使用情况。使用explain,可以分析出需要在哪里加上索引,以及调整表的连接,以达到优化查询的目的;explain命令之后不仅可以跟select语句,也可以跟delete,insert,update,replace语句。

用法

只需要在sql语句前加上explain就可以了,比如:

+—-+————-+——-+————+——+—————+——+———+——+——–+———-+——-+

| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |

+—-+————-+——-+————+——+—————+——+———+——+——–+———-+——-+

| 1 | SIMPLE | user | NULL | ALL | NULL | NULL | NULL | NULL | 100310 | 100.00 | NULL |

+—-+————-+——-+————+——+—————+——+———+——+——–+———-+——-+

如何分析

我们看到explain命令的结果有很多列,通常情况下,我们最关心的指标是select_type和type。

概念

Column

JSON Name

Meaning

select_id

The SELECT identifier(选择标识符)

None

The SELECT type(查询类型)

table_name

The table for the output row(结果集使用的表)

partitions

The matching partitions(匹配的分区)

access_type

The join type(连接类型)

possible_keys

The possible indexes to choose(可能使用到的索引)

key

The index actually chosen(实际使用的索引)

key_length

The length of the chosen key (使用索引的长度)

ref

The columns compared to the index(和索引比较的列)

rows

Estimate of rows to be examined(扫描的行数)

filtered

Percentage of rows filtered by table condition(表条件过滤行数的百分比)

None

Additional information(附加的信息)

进一步解释

id

id的值越大,执行的优先级越高,id相同,则从上往下顺序执行。所以以下例子:

id

placeholder

1

A

1

B

2

C

执行的顺序是:C,A,B。

select_type

select_type Value

JSON Name

Meaning(含义)

SIMPLE

None

Simple SELECT (not using UNION or subqueries)(查询查询,不使用union或子查询)

PRIMARY

None

Outermost SELECT(最外层的select查询)

None

Second or later SELECT statement in a UNION (在union中排在第二位甚至更靠后的select语句)

DEPENDENT UNION

dependent (true)

Second or later SELECT statement in a UNION, dependent on outer query (在union中排在第二位甚至更靠后的select语句,取决于外面的查询)

UNION RESULT

union_result

Result of a UNION.(union结果集)

None

First SELECT in subquery(子查询中的第一个select)

DEPENDENT SUBQUERY

dependent (true)

First SELECT in subquery, dependent on outer query(子查询中的第一个select,取决于外面的查询)

DERIVED

None

Derived table(派生表)

DEPENDENT DERIVED

dependent (true)

Derived table dependent on another table (派生表,依赖其他表)

MATERIALIZED

materialized_from_subquery

Materialized subquery (实现子查询)

UNCACHEABLE SUBQUERY

cacheable (false)

A subquery for which the result cannot be cached and must be re-evaluated for each row of the outer query(结果不能被缓存并且外部查询的每一行都必须被重新评估的子查询)

UNCACHEABLE UNION

cacheable (false)

The second or later select in a UNION that belongs to an uncacheable subquery (see UNCACHEABLE SUBQUERY)(在union中排位第二甚至更靠后属于不能缓存的子查询)

table

显示这行的数据是关于哪张表的,也可能是表的别名。

type

可能的取值

null > system > const > eq_ref > ref > range > index > all,从左到右,性能递减,null最好,all最差,一般的,最好能优化查询到const到range之间。

含义

ALL:Full Table Scan,遍历全表。

index: Full Index Scan,index与ALL区别为index类型只遍历索引树,不遍历数据行,所以比all的速度要快。

range: 只检索给定范围的行,这个范围必须应用在一个有索引的列上。

ref: 使用了非唯一索引作为where或join条件,是一个确定的值。

eq_ref: 同ref,但索引是唯一索引。

const、system: 将确定的值应用在索引(unique and not unique)上,type将会是const,当结果只有一行时,type是system。

NULL: MySQL在优化过程中分解语句,执行时甚至不用访问表或索引,例如从一个索引列里选取最小值可以通过单独索引查找完成。

例子

每一个type都给出了一个例子:

drop table t1, t2, t3;

create table t1 (

id int(11) auto_increment,

name varchar(50),

address varchar(100),

primary key (id),

key index_name(name)

);

create table t2 (

id int(11) auto_increment,

name varchar(50),

address varchar(100),

primary key (id),

key index_name(name)

);

create table t3 (

id int(11) auto_increment,

name varchar(50),

address varchar(100),

primary key (id),

key index_name(name)

);

insert into t1 (name, address)

values (‘tom’, ‘downtown’),

(‘jack’, ‘country yard’);

insert into t2 (name, address)

values (‘tom’, ‘downtown’),

(‘jack’, ‘country yard’);

insert into t3 (name, address)

values (‘tom’, ‘downtown’),

(‘jack’, ‘country yard’);

explain select *

from t1

where id = 1; — const

explain select *

from t1

limit 10; — all

explain select *

from t1

where name = ‘tom’; — ref

explain select t1.id

from t1,

t2

where t1.id = t2.id; — index, eq_ref

explain select t1.*

from t1,

t2

where t1.id = t2.id; — index, all

explain select *

from t1

where id between 1 and 10; — range

explain select t1.name

from t1,

t2

where t1.name = t2.name; — index, ref

explain select *

from t2,

(select id from t1 where t1.id = 1) t

where t2.id = t.id;

explain select *

from (select * from t1 where t1.address = ‘downtown’) t;

explain select *

from t1

where id = 1

union

select *

from t2

where id = 2; — const,const,all

explain select *

from (select * from t1 limit 1) a1; — system, all

Extra

Using where:不用读取表中所有信息,仅通过索引就可以获取所需数据,这发生在对表的全部的请求列都是同一个索引的部分的时候,表示mysql服务器将在存储引擎检索行后再进行过滤。

Using temporary:表示MySQL需要使用临时表来存储结果集,常见于排序和分组查询,常见 group by ; order by。

Using filesort:当Query中包含 order by 操作,而且无法利用索引完成的排序操作称为“文件排序”。

Using join buffer:该值强调了在获取连接条件时没有使用索引,并且需要连接缓冲区来存储中间结果。如果出现了这个值,那应该注意,根据查询的具体情况可能需要添加索引来改进能。

Impossible where:这个值强调了where语句会导致没有符合条件的行(通过收集统计信息不可能存在结果)。

Select tables optimized away:这个值意味着仅通过使用索引,优化器可能仅从聚合函数结果中返回一行

No tables used:Query语句中使用from dual 或不含任何from子句。

应用

在很多博客上,都有关于between,>,

create table user (

id int(11) auto_increment,

name varchar(100),

age int(11),

primary key (id),

key index_age(age),

key index_name(name)

);

explain select * from user where name in (‘tom’); — use

explain select * from user where name = ‘tom’; — use

explain select * from user where name between ‘tom’ and ‘jerry’; — not use

explain select * from user where name <> ‘tom’; — not use

explain select * from user where name = ‘tom’ or name = ‘jerry’; — use

explain select * from user where name like ‘om%’; — use

explain select * from user where name like ‘tom’; — use, 这里的like相当于等号

explain select * from user where name like ‘%to’; — not use

explain select * from user where age between 0 and 1; — use

explain select * from user where age not between 0 and 1; — not use

explain select * from user where age > 50; — not use

explain select * from user where age < 50; — not use

explain select * from user where age != 3; — not use

explain select * from user where age in (1, 99); — use

explain select * from user where age = 1 or age = 3; — use

explain select * from user where age like ‘1%’; — not use

explain select * from user where age like ‘%1’; — not use

从以上的测试结果,我们可以得出结论:

between and, >,,

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/180675.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • wireshark中抓取ICMP报文「建议收藏」

    wireshark中抓取ICMP报文「建议收藏」为了更有效地转发IP数据报和提高交付成功的机会,在网络层使用了网际控制报文协议ICMP(InternetControlMessageProtocol)[RFC792]。它是TCP/IP协议族的一个子协议,用于在IP主机、路由器之间传递控制消息。ICMP报文作为IP层数据报的数据,加上数据报的首部,组成数据报发送出去。ICMP报文的种类有两种,即ICMP差错报告报文和ICMP询问报文…

  • jq正则表达式_JAVA 正则表达式

    jq正则表达式_JAVA 正则表达式一、JavaScript正则表达式正则表达式(英语:RegularExpression,在代码中常简写为regex、regexp或RE)使用单个字符串来描述、匹配一系列符合某个句法规则的字符串搜索模式。搜索模式可用于文本搜索和文本替换。什么是正则表达式?正则表达式是由一个字符序列形成的搜索模式。当你在文本中搜索数据时,你可以用搜索模式来描述你要查询的内容。正则表达式可以是一个简单的字符,或一个更…

  • 初识ABP vNext(10):ABP设置管理

    初识ABP vNext(10):ABP设置管理

    2020年11月20日
  • python 数组添加数组_Python添加到数组[通俗易懂]

    python 数组添加数组_Python添加到数组[通俗易懂]python数组添加数组Pythondoesn’thaveanyspecificdatatypeasanarray.WecanuseListthathasallthecharacteristicsofanarray.Python没有任何特定的数据类型作为数组。我们可以使用具有数组所有特征的List。Pythonarraymodulecan…

  • nfc手机与手机数据传输_iphone数据传输已取消

    nfc手机与手机数据传输_iphone数据传输已取消我正在尝试为医院开发Android应用程序.在该系统中,需要使用NFC技术将存储在Android手机中的数据库中的患者信息获取到台式计算机中.无论如何我在哪里可以使用NFCUSB读取设备(ACR122UNFC智能卡读卡器RFID编写器5MifareUSB)将数据从手机传输到我的台式电脑?真实情况是,在医院,当一个人想要获得一些测试结果时,他将到达柜台并将移动设备放置在安装在柜台上的NFC读…

  • idea 2021激活码破解方法

    idea 2021激活码破解方法,https://javaforall.cn/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号