关于typescript:数栈技术分享解读MySQL执行计划的type列和extra列

3次阅读

共计 3247 个字符,预计需要花费 9 分钟才能阅读完成。


一、解读 type

执行打算的 type 示意拜访数据类型,有很多种拜访类型。

1、system
示意这一步只返回一行数据,如果这一步的执行对象是一个驱动表或者主表,那么被驱动表或者子查问只是被拜访一次。

2、const

示意这个执行步骤最多只返回一行数据。const 通常呈现在对主键或惟一索引的等值查问中,例如对表 t 主键 id 的查问:

3、eq_ref

eq_ref 类型个别意味着在表关联时,被关联表上的关联列走的是主键或者惟一索引。例如,表 jiang 关联 lock_test 表,关联列别离是两张表的主键列:

下面 SQL 执行时,jiang 表是驱动表,lock_test 是被驱动表,被驱动表的关联列是主键 id,type 类型为 eq_ref。

所以,对于 eq_ref 类型来说有一个重要的特点就是:这一步波及到的表是被驱动表;这一步中应用到惟一索引或主键。除了 system 和 const 之外,这是成果最好的关联类型。

4、ref

与下面相同,如果执行打算的某一步的 type 是 ref 的话,示意这一步的关联列是非惟一索引。例如,用表 jiang 的主键 id 列关联表 lock_test 的 num 列,num 列上建设了一般索引:

下面 SQL 执行时,表 jiang 是驱动表,lock_test 是被驱动表,被驱动表上走的是非惟一索引,type 类型为 ref。

所以 ref 的特点是:示意这一步拜访数据应用的索引是非惟一索引。

5、Ref_or_null
例如执行上面语句:

示意走了索引(num 列上有索引),然而也拜访了空值。

6、index_merge

示意索引合并,个别对多个二级索引列做 or 操作时就会产生索引合并。
例如执行下列语句:
mysql> explain select * from lock_test where id=3 or num=4;

id 为主键,num 列上建有一般索引,语句执行时,会通过两个单列索引来解决 or 操作。

7、unique_subquery
示意惟一子查问。例如有如下语句执行时:
value in(select primary_key from single_table where …)
对于 in 子句来说,当 in 子句里的子查问返回的是某一个表的主键时,type 显示为 unique subquery。

8、index_subquery
当有如下语句执行时:
value in(select key_column from single_table where …)
与下面的类似,示意对于 in 子句来说,当 in 子句里的子查问返回的是某一个表的二级索引列 (非主键列) 时,type 显示为 index_subquery。

9、range:
在有索引的列上取一部分数据。常见于在索引列上执行 between and 操作。

10、index:
索引全扫描,个别产生在笼罩索引的时候,也就是对有索引列产生一次全扫描。

11、all:
没有索引的全表扫描。
一个特例:

Explain select * from stu limit 1,1;
二、解读 extra

1、using where:
个别有两层意思:
示意通过索引拜访时,须要再回表拜访所需的数据;
过滤条件产生在 server 层而不是存储引擎层;
如果执行打算中显示走了索引,然而 rows 值很高,extra 显示为 using where,那么执行成果就不会很好。因为索引拜访的老本次要在回表上,这时能够采纳笼罩索引来优化。
通过笼罩索引也能将过滤条件下压,在存储引擎层执行过滤操作,这样成果是最好的。
所以,笼罩索引是解决 using where 的最无效的伎俩。

2、using index condition
示意将过滤下压到存储层执行,避免 server 层过滤过多数据
如果 extra 中呈现了 using index condition,阐明对拜访表数据进行了优化。

3、using temporary
示意语句执行过程中应用到了长期表。以下子句的呈现可能会应用到长期表:
order by
group by
distinct
union 等
数据不能间接返回给用户,就须要缓存,数据就以长期表缓存在用户工作空间。留神,可能会呈现磁盘长期表,须要关注须要缓存的数据的 rows。
能够应用索引打消下面的四个操作对应的长期表。

4、using sort_union(indexs)
比方当执行上面语句:

Sname 和 sphone 列上都有索引,这时执行打算的 extra 项就会显示 using sort_union(i_sname,i_spone),示意索引合并。常随同着 index_merge。

5、using MRR:
个别通过二级索引拜访表数据的过程是:先拜访二级索引列,找到对应的二级索引数据后就失去对应的主键值,而后拿着这个主键值再去拜访表,取出行数据。这样取出的数据是依照二级索引排序的。
MRR 示意:通过二级索引失去对应的主键值后,不间接拜访表而是先存储起来,在失去所有的主键值后,对主键值进行排序,而后再拜访表。这样能够大幅减低对表的拜访次数,至多实现了程序拜访表。
MRR 的一个长处就是晋升索引拜访表的效率,也就是升高了回表的老本。然而有一个比拟大的问题:取出来的数据就不依照二级索引排序了。

6、using join buffer(Block Nested Loop)
BNL 次要产生在两个表关联时,被关联的表上没有索引。
BNL 示意这样的意思:A 关联 B,A 的关联列上有索引而 B 的没有。这时就会从 A 表中取 10 行数据拿进去放到用户的 join buffer 空间中,而后再取 B 上的数据和 join buffer 中 A 的关联列进行关联,这时只须要对 B 表拜访一次,也就是 B 表产生一次全表扫描。
如果 join buffer 中的 10 行数据关联完后,就再取 10 行数据持续和 B 表关联,始终到 A 表的所有数据都关联完为止。
从下面能够看进去,这种形式大略效率会进步约 90%。

7、using join buffer(Batched Key Access)
个别呈现 BKA 的状况是:表关联时,被驱动表上有索引,然而驱动表返回的行数太多。
当呈现上述情况时,就会将驱动表的返回后果集放到用户工作空间的 join buffer 中,而后取后果集的一条记录去关联被驱动表的索引关联列。失去相应的主键列后并不马上通过这个主键列去被被驱动表中取数据,而是先寄存到工作空间中。等到后果集中的所有数据都关联完了,对工作空间中的所有通过关联失去主键列进行排序,而后对立拜访被驱动表,从中取数据。这样的益处就是大大降低了拜访的次数。
从下面能够看出:BKA 用到了 MRR 技术;BKA 适宜驱动表返回行数较多、被驱动表拜访时走的是索引的状况。
这个性能能够关上或者敞开:
Set optimizer_switch=’mrr=on,batched_key_access=on’;

8、using index for group by
示意通过复合索引实现 group by, 不必回表。
例如复合索引(a,b),执行语句:select a from tb group by b; 时就会呈现 using index for group by。

9、using index

示意实现了笼罩索引扫描;也就是须要拜访的数据都在索引中,不须要回表。在个别状况下,缩小不必要的数据拜访可能晋升效率。

例如对表 lock_test 取 num 列上的数据,num 列上建设一般索引:

10、using filesort
阐明有排序行为,然而不肯定是磁盘排序。

11、materialize scan
对物化表的全扫描,因为物化表就是一个长期表,表上没有索引。

数栈是云原生—站式数据中台 PaaS,咱们在 github 和 gitee 上有一个乏味的开源我的项目:FlinkX,FlinkX 是一个基于 Flink 的批流对立的数据同步工具,既能够采集动态的数据,也能够采集实时变动的数据,是全域、异构、批流一体的数据同步引擎。大家喜爱的话请给咱们点个 star!star!star!

github 开源我的项目:https://github.com/DTStack/fl…

gitee 开源我的项目:https://gitee.com/dtstack_dev…

正文完
 0