MySQL中explain执⾏计划中额外信息字段(Extra)详解
SQL执⾏计划是经过优化器决策,产⽣的SQL在数据库内部执⾏的访问路径计划;
redis数据类型底层实现原理由如下语法得到:
explain select col1,col2 from t1..;
desc select col1,col2 from t1..;
理解输出各个列的含义
id:每个select⼦句的标识id
select_type:select语句的类型
table:当前表名
显⽰查询将访问的分区,如果你的查询是基于分区表
type:当前表内访问⽅式
possible_keys:可能使⽤到的索引
key:经过优化器评估最终使⽤的索引
key_length:使⽤到的索引长度
ref:引⽤到的上⼀个表的列
rows:rows_examined,要得到最终记录索要扫描经过的记录数
filtered:表⽰存储引擎返回的数据在server层过滤后,剩下多少满⾜查询的记录数量的⽐例,注意是百分⽐,不是具体记录数。
Extra:额外的信息说明
接下来主要针对extra字段进⾏详细解释,EXPLAIN输出的Extra列包含有关MySQL如何解析查询的其他信息。此字段能够给出让我们深⼊理解执⾏计划进⼀步的细节信息,⽐如是否使⽤ICP,MRR等。
⾸先说明下在extra字段进⾏测试过程中使⽤到的表和MySQL版本:
CREATE TABLE `t est_extra1` (
`i d` int(11) NOT NULL AUTO_INCREMENT,
`e mp_number` int(11) NOT NULL,
`n ame` varchar(30) NOT NULL DEFAULT '',
`a ge` int(11) DEFAULT NULL,
`a ddress` varchar(50) DEFAULT NULL,
`r egion` varchar(20) DEFAULT NULL,
PRIMARY KEY (`i d`),
KEY `i dx_empnumber` (`e mp_number`),
KEY `i dx_region` (`r egion`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `t est_extra2` (
`i d` int(11) NOT NULL AUTO_INCREMENT,
`n ame` varchar(30) NOT NULL DEFAULT '',
`e mp_number` int(11) NOT NULL,
`s alary` decimal(10,2) NOT NULL DEFAULT '0.00',
PRIMARY KEY (`i d`),
UNIQUE KEY `i dx_empnumber` (`e mp_number`),
KEY `i dx_name` (`n ame`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
mysql> select @@version;
+-----------+
| @@version |
+-----------+
| 5.7.14    |
+-----------+
1 row in set (0.00 sec)
extra字段详细解释说明:
const row not found
For a query such as SELECT … FROM tbl_name, the table was empty.(类似于select …. from tbl_name,⽽表记录为空)
Deleting all rows
For DELETE, some storage engines (such as MyISAM) support a handler method that removes all table rows in a simple and fast way. This Extra value is displayed if the engine uses this optimization.
(对于DELETE,⼀些存储引擎(如MyISAM)⽀持⼀种处理⽅法,可以简单⽽快速地删除所有的表⾏。 如果引擎使⽤此优化,则会显⽰此额外值)
Distinct
MySQL is looking for distinct values, so it stops searching for more rows for the current row combination after it has found the first matching row.(MySQL正在寻不同的值,因此在到第⼀个匹配⾏后,它将停⽌搜索当前⾏组合的更多⾏)
FirstMatch
The semi-join FirstMatch join shortcutting strategy is used for tbl_name. (半连接去重执⾏优化策略,当匹配了第⼀个值之后⽴即放弃之后记录的搜索。这为表扫描提供了⼀个早期退出机制⽽且还消除了不必要记录的产⽣);如下图所⽰:
注:半连接: 当⼀张表在另⼀张表到匹配的记录之后,半连接(semi-jion)返回第⼀张表中的记录。与条件连接相反,即使在右节点中到⼏条匹配的记录,左节点的表也只会返回⼀条记录。另外,右节点的表⼀条记录也不会返回。半连接通常使⽤IN或EXISTS 作为连接条件。
Start temporary, End temporary
java map遍历例子表⽰半连接中使⽤了DuplicateWeedout策略的临时表,具体实现过程如下图所⽰:
Full scan on NULL key
This occurs for subquery optimization as a fallback strategy when the optimizer cannot use an index-lookup access method.(⼦查询中的⼀种优化⽅式,主要在遇到⽆法通过索引访问null值的使⽤)
)
The semi-join LooseScan strategy is used. m and n are key part numbers. 利⽤索引来扫描⼀个⼦查询表可以从每个⼦查询的值组中选出⼀个单⼀的值。松散扫描(LooseScan)策略采⽤了分组,⼦查询
中的字段作为⼀个索引且外部SELECT语句可以可以与很多的内部SELECT记录相匹配。如此便会有通过索引对记录进⾏分组的效果。
如下图所⽰:
mysql语句的执行顺序Impossible HAVING
The HAVING clause is always false and cannot select any rows.(HAVING⼦句总是为false,不能选择任何⾏)
Impossible WHERE
The WHERE clause is always false and cannot select any rows.(WHERE⼦句始终为false,不能选择任何⾏)
Impossible WHERE noticed after reading const tables
MySQL has read all const (and system) tables and notice that the WHERE clause is always false.(MySQL读取了所有的const和system表,并注意到WHERE⼦句总是为false)
No matching min/max row
No row satisfies the condition for a query such as SELECT MIN(…) FROM … WHERE condition.(没有满⾜SELECT
MIN(…)FROM … WHERE查询条件的⾏)
⽰例中,emp_number最⼩值为1001,没有满⾜条件的⾏:
如果此时将select字段改为其他字段,⽐如salary,则extra如下显⽰,使⽤到ICP优化机制(ICP机制见)
no matching row in const table
For a query with a join, there was an empty table or a table with no rows satisfying a unique index condition.(表为空或者表中根据唯⼀键查询时没有匹配的⾏)
No matching rows after partition pruning
For DELETE or UPDATE, the optimizer found nothing to delete or update after partition pruning. It is similar in meaning to Impossible WHERE for SELECT statements.(对于DELETE或UPDATE,优化器在分区修剪后没有发现任何删除或更新。 对于SELECT语句,它与Impossible WHERE的含义相似)
No tables used
The query has no FROM clause, or has a FROM DUAL clause.(没有FROM⼦句或者使⽤DUAL虚拟表)
.注:DUAL虚拟表纯粹是为了⽅便那些要求所有SELECT语句应该有FROM和可能的其他⼦句的⼈。 MySQL可能会忽略这些条款。如果没有引⽤表,MySQL不需要FROM DUAL()
Not exists
MySQL能够对查询执⾏LEFT JOIN优化,并且在到与LEFT JOIN条件匹配的⼀⾏后,不会在上⼀⾏组合中检查此表中的更多⾏。例如:
SELECT * FROM t1 LEFT JOIN t2 ON t1.id = t2.id
WHERE t2.id IS NULL;深圳web前端学校
假设t2.id被定义为NOT NULL。 在这种情况下,MySQL会扫描t1,并使⽤t1.id的值查t2中的⾏。 如果MySQL在t2中到⼀个匹配的⾏,它会知道t2.id永远不会为NULL,并且不扫描t2中具有相同id值的其余⾏。 换句话说,对于t1中的每⼀⾏,MySQL只需要在t2中只执⾏⼀次查,⽽不考虑在t2中实际匹配的⾏数。
Range checked for each record (index map: N)
ajax实现步骤MySQL发现没有使⽤好的索引,但是发现在前⾯的表的列值已知之后,可能会使⽤⼀些索引。 对于上表中的每⼀⾏组合,MySQL检查是否可以使⽤range或index_merge访问⽅法来检索⾏。 这不是很快,但⽐执⾏没有索引的连接更快。
index map N索引的编号从1开始,按照与表的SHOW INDEX所⽰相同的顺序。 索引映射值N是指⽰哪些索引是候选的位掩码值。 例如,0x19(⼆进制11001)的值意味着将考虑索引1,4和5。
其中name属性为varchar类型;但是条件给出整数型,涉及到隐式转换。
图中t2也没有⽤到索引,是因为查询之前我将t2中name字段排序规则改为utf8_bin导致的链接字段排序规则不匹配。
游戏开发学什么专业

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。