的解释
statement提供MySQL如何执行语句的信息。解释
适用于选择
,删除
,插入
,取代
,更新
语句。
解释
类中使用的每个表返回一行信息选择
声明。它按照MySQL在处理语句时读取表的顺序列出了输出中的表。MySQL使用嵌套循环连接方法解析所有连接。这意味着MySQL从第一个表中读取一行,然后在第二个表、第三个表中查找匹配的行,以此类推。处理完所有表后,MySQL输出所选的列,并通过表列表进行回溯,直到找到有更多匹配行的表。从该表中读取下一行,然后继续处理下一个表。
解释
输出包括分区信息。同时,为选择
语句,解释
生成可以显示的扩展信息显示警告
后,解释
(见第8.8.3节,“扩展EXPLAIN输出格式”).
在旧的MySQL版本中,分区和扩展信息是使用解释分区
而且解释扩展
.这些语法仍然可以被识别为向后兼容性,但分区和扩展输出现在默认启用,因此分区
而且扩展
关键字是多余的,不推荐使用。使用它们会导致警告;期望他们从解释
语法,在未来的MySQL版本。
不能使用已弃用的分区
而且扩展
关键词在一起是一样的解释
声明。此外,这两个关键字都不能与格式
选择。
MySQL工作台有一个可视化解释功能,它提供了一个可视化的表示解释
输出。看到教程:使用Explain提高查询性能.
的每个输出行解释
提供关于一个表的信息。中总结的值表8.1,“EXPLAIN输出列”,并在下表中详细描述。列名显示在表的第一列中;第二列提供输出中显示的等效属性名= JSON格式
使用。
JSON属性零
不显示在json格式解释
输出。
的
选择
标识符。这是选择
在查询中。取值为零
如果行指向其他行的并集结果。在这种情况下,表格
列显示如下的值<联盟
表示行的并集米
,N
>id
的值米
而且N
.的类型
选择
,可以是下表中所示的任何一个。一个json格式的解释
暴露了选择
类型的属性query_block
,除非是简单的
或主要的
.JSON名称(如果适用)也显示在表中。select_type
价值JSON的名字 意义 简单的
没有一个 简单的 选择
(不使用联盟
或子查询)主要的
没有一个 最外层 选择
联盟
没有一个 第二或更高 选择
中的语句联盟
依赖联盟
依赖
(真正的
)第二或更高 选择
中的语句联盟
,依赖于外部查询联盟的结果
union_result
的结果 联盟
.子查询
没有一个 第一个 选择
在子查询相关子查询
依赖
(真正的
)第一个 选择
在子查询中,依赖于外部查询派生的
没有一个 派生表 物化
materialized_from_subquery
物化子查询 当前子查询
缓存
(假
)一个子查询,其结果不能被缓存,必须为外部查询的每一行重新计算 各种联盟
缓存
(假
)中的第二个或后面的选择 联盟
它属于一个不可缓存的子查询(参见当前子查询
)依赖
通常表示使用相关的子查询。看到13.2.10.7节,“相关子查询”.相关子查询
评价不同于当前子查询
评估。为相关子查询
时,子查询只对来自外部上下文的每一组变量的不同值重新求值一次。为当前子查询
,子查询将为外层上下文的每一行重新计算。子查询的可缓存性不同于查询缓存中的查询结果缓存(在章节8.10.3.1,“查询缓存如何运行”).子查询缓存发生在查询执行期间,而查询缓存仅用于在查询执行完成后存储结果。
当你指定
= JSON格式
与解释
时,输出没有一个直接等价的属性select_type
;的query_block
属性对应于给定的选择
.属性相当于大部分的选择
刚才显示的子查询类型是可用的(例如materialized_from_subquery
为物化
),并在适当时显示。没有等价的JSON简单的
或主要的
.的
select_type
非-选择
Statements显示受影响表的语句类型。例如,select_type
是删除
为删除
语句。输出行所引用的表的名称。它也可以是以下值之一:
<联盟
:行表示与的行并集米
,N
>id
的值米
而且N
.<派生
:该行引用具有N
>id
的价值N
.类中的子查询可以生成派生表从
条款。<子查询
属性行的实体化子查询结果N
>id
的价值N
.看到第8.2.2.2节,“用物化优化子查询”.
查询将从中匹配记录的分区。取值为
零
对于非分区表。看到第22.3.5节“获取分区信息”.连接类型。有关不同类型的描述,请参见
解释
连接类型.possible_keys
(JSON的名字:possible_keys
)的
possible_keys
column表示MySQL可以从中选择查找该表中的行的索引。注意,该列与输出中显示的表的顺序完全无关解释
.这意味着一些关键possible_keys
可能无法在实际中使用生成的表顺序。如果这一列是
零
(或者在json格式的输出中未定义),没有相关的索引。方法可以提高查询的性能在哪里
子句,以检查它是否引用某个或多个适合建立索引的列。如果是,则创建适当的索引并使用解释
再一次。看到第13.1.8节“ALTER TABLE语句”.要查看表有哪些索引,请使用
显示索引来自
.tbl_name
的
关键
列表示MySQL实际决定使用的键(索引)。如果MySQL决定使用possible_keys
索引查找行,该索引被列为键值。这是可能的
关键
类中不存在的索引的名称possible_keys
价值。如果没有possible_keys
索引适用于查找行,但是查询所选择的所有列都是其他索引的列。也就是说,命名索引覆盖选定的列,因此尽管不使用它来确定检索哪些行,但索引扫描比数据行扫描更有效。为
InnoDB
,即使查询还选择主键,辅助索引也可能覆盖所选列,因为InnoDB
用每个辅助索引存储主键值。如果关键
是零
, MySQL发现没有索引可以更有效地执行查询。中列出的索引,强制MySQL使用或忽略
possible_keys
列,使用力指数
,使用索引
,或忽略指数
在您的查询中。看到第8.9.4节“索引提示”.为
MyISAM
表、运行分析表
帮助优化器选择更好的索引。为MyISAM
表,myisamchk——分析也一样。看到13.7.2.1节“ANALYZE TABLE语句”,第7.6节,“MyISAM表维护和崩溃恢复”.的
key_len
列表示MySQL决定使用的键的长度。的价值key_len
使您可以确定MySQL实际使用的多部分键的多少部分。如果关键
列表示零
,key_len
列还说零
.由于键存储格式的原因,对于可以为的列,键长度要大1
零
而不是非空
列。的
裁判
类中指定的索引与哪些列或常量进行比较关键
列从表中选择行。如果值为
函数
,所使用的值是某个函数的结果。要查看哪个函数,请使用显示警告
后解释
为了看到延伸的解释
输出。函数实际上可能是一个运算符,例如算术运算符。的
行
column表示MySQL认为执行查询必须检查的行数。为
InnoDB
表,这个数字是一个估计,并不总是准确的。的
过滤后的
列指示由表条件过滤的表行的估计百分比。最大值为100,这意味着没有发生行过滤。从100开始递减的值表示过滤量的增加。行
显示检查和的估计行数行
×过滤后的
显示与下表连接的行数。例如,如果行
是1000和过滤后的
为50.00(50%),则与下表连接的行数为1000 × 50% = 500。本列包含关于MySQL如何解析查询的附加信息。有关不同值的说明,请参见
解释
额外的信息.属性对应的JSON属性不存在
额外的
列;对象的文本或JSON属性公开此列中可能出现的值消息
财产。
的类型
列的解释
输出描述了表是如何连接的。的值在json格式的输出中找到access_type
财产。下面的列表描述了连接类型,从最好的类型到最差的:
该表只有一行(= system表)。这是一个特例
常量
连接类型。该表最多有一个匹配行,在查询开始时读取。因为只有一行,这一行中的列的值可以被优化器的其余部分视为常量。
常量
表非常快,因为它们只被读取一次。常量
比较语句的所有部分时使用主键
或独特的
索引到常数值。在以下查询中,tbl_name
可以用作常量
表:Select * fromtbl_name在哪里primary_key= 1;Select * fromtbl_name在哪里primary_key_part1= 1,primary_key_part2= 2;
对于前几个表中的每个行组合,从该表中读取一行。除了
系统
而且常量
类型,这是最好的连接类型。当连接使用索引的所有部分并且索引为主键
或唯一的非空
索引。eq_ref
可以用于使用?方法进行比较的索引列=
操作符。比较值可以是一个常量,也可以是一个表达式,该表达式使用在此表之前读取的表中的列。在下面的例子中,MySQL可以使用eq_ref
加入流程ref_table
:Select * fromref_table,other_table在哪里ref_table.key_column=other_table.列;Select * fromref_table,other_table在哪里ref_table.key_column_part1=other_table.列和ref_table.key_column_part2= 1;
对于前几个表中的每个行组合,从该表中读取具有匹配索引值的所有行。
裁判
如果连接仅使用键的最左边的前缀,或者如果键不是主键
或独特的
索引(换句话说,如果联接不能基于键值选择单行)。如果所使用的键只匹配几行,则这是一个很好的连接类型。裁判
可以用于使用?方法进行比较的索引列=
或< = >
操作符。在下面的例子中,MySQL可以使用裁判
加入流程ref_table
:Select * fromref_table在哪里key_column=expr;Select * fromref_table,other_table在哪里ref_table.key_column=other_table.列;Select * fromref_table,other_table在哪里ref_table.key_column_part1=other_table.列和ref_table.key_column_part2= 1;
连接使用
全文
索引。这种连接类型类似于
裁判
,但是MySQL会额外搜索包含零
值。这种连接类型优化最常用于解析子查询。在下面的例子中,MySQL可以使用ref_or_null
加入流程ref_table
:Select * fromref_table在哪里key_column=expr或key_column是零;
此连接类型表示使用索引合并优化。在这种情况下,
关键
列中包含使用的索引列表,和key_len
包含所使用索引的最长键部分的列表。有关更多信息,请参见章节8.2.1.3,“索引合并优化”.此类型替换
eq_ref
对于一些在
以下形式的子查询:价值(选择primary_key从single_table在哪里some_expr)
unique_subquery
只是一个索引查找函数,完全替换子查询以提高效率。此连接类型类似于
unique_subquery
.它取代在
子查询,但它适用于以下形式的子查询中的非唯一索引:价值(选择key_column从single_table在哪里some_expr)
只检索给定范围内的行,使用索引选择行。的
关键
输出行的列指示使用哪个索引。的key_len
包含所使用的最长的键部分。的裁判
列是零
对于这种类型。范围
将键列与常量进行比较时,可以使用=
,<>
,>
,> =
,<
,< =
,为空
,< = >
,之间的
,就像
,或在()
运营商:Select * fromtbl_name在哪里key_column= 10;Select * fromtbl_name在哪里key_column10到20之间;Select * fromtbl_name在哪里key_column在(10年,20年,30);Select * fromtbl_name在哪里key_part1= 10 andkey_part2在(10年,20年,30);
的
指数
连接类型与所有
,除了扫描索引树。这有两种方式:如果索引是查询的覆盖索引,并且可以用于满足表中所需的所有数据,则只扫描索引树。在这种情况下,
额外的
列表示使用索引
.仅索引扫描通常比所有
因为索引的大小通常小于表数据。使用从索引中读取数据来按索引顺序查找数据行,执行全表扫描。
使用索引
不出现在额外的
列。
当查询只使用作为单个索引一部分的列时,MySQL可以使用这种连接类型。
对前一个表中的每个行组合执行全表扫描。如果表是第一个没有标记的表,这通常是不好的
常量
,通常非常其他情况都不好。通常情况下,你可以避免所有
通过添加索引,支持基于常量值或早期表中的列值从表中检索行。
的额外的
列的解释
输出包含MySQL如何解析查询的附加信息。下面的列表说明了可以出现在此列中的值。每个项还指示对于json格式的输出,哪个属性显示额外的
价值。对于其中一些,有一个特定的性质。的文本显示消息
财产。
如果您想使您的查询尽可能快,请注意额外的
的列值使用filesort
而且使用临时
,或者json格式的解释
输出,using_filesort
而且using_temporary_table
属性等于真正的
.
'的孩子
(JSON:表格
推送join@1消息
文本)的子表引用
表格
在一个可以下推到NDB内核的连接中。仅适用于NDB集群,当下推连接启用时。的描述ndb_join_pushdown
服务器系统变量获取更多信息和示例。未找到Const行
(JSON属性:const_row_not_found
)对于查询,例如
选择……从
当我离开时,桌子是空的。tbl_name
删除所有行
(JSON属性:消息
)为
删除
,一些存储引擎(如MyISAM
)支持一个处理程序方法,以简单和快速的方式删除所有表行。这额外的
如果引擎使用此优化,则显示。截然不同的
(JSON属性:截然不同的
)MySQL正在寻找不同的值,因此在找到第一个匹配的行之后,它会停止为当前行组合搜索更多的行。
FirstMatch (
(JSON属性:tbl_name
)first_match
)半连接FirstMatch连接捷径策略用于
tbl_name
.对NULL键进行完整扫描
(JSON属性:消息
)当优化器不能使用索引查找访问方法时,子查询优化作为一种回退策略会出现这种情况。
不可能有
(JSON属性:消息
)的
有
子句总是false,不能选择任何行。不可能的,
(JSON属性:消息
)的
在哪里
子句总是false,不能选择任何行。不可能在读取const表后注意到WHERE
(JSON属性:消息
)LooseScan (
(JSON属性:米
..n
)消息
)使用半连接LooseScan策略。
米
而且n
是关键零件号。没有匹配的最小/最大行
(JSON属性:消息
)没有行满足查询的条件,例如
选择最小值(…)从…在哪里
.条件
const表中没有匹配的行
(JSON属性:消息
)对于具有连接的查询,存在一个空表或一个表中没有满足唯一索引条件的行。
分区修剪后没有匹配的行
(JSON属性:消息
)没有使用表
(JSON属性:消息
)查询没有
从
从句,或有从双
条款。为
插入
或取代
语句,解释
当没有时显示此值选择
部分。例如,它出现在解释INSERT INTO t VALUES(10)
因为它等于解释插入t从对偶中选择10
.不存在
(JSON属性:消息
)MySQL能够做一个
左连接
查询上的优化,并且在找到与上一个行组合匹配的行后,不检查此表中的更多行左连接
标准。下面是一个可以这样优化的查询类型的例子:SELECT * FROM t1左连接t2在t1.id=t2。id WHERE t2。id为NULL;
假设
t2.id
定义为非空
.在这种情况下,MySQL进行扫描t1
然后查找里面的行t2
使用的值t1.id
.如果MySQL在中找到匹配的行t2
,它知道t2.id
永远不可能零
,并且不扫描其余的行t2
都是一样的id
价值。换句话说,对于每一行t1
, MySQL只需要做一个查找t2
,不管实际匹配了多少行t2
.计划还没准备好
(JSON属性:none)此值出现在
连接说明
当优化器尚未为在命名连接中执行的语句创建执行计划时。如果执行计划输出包含多行,则其中任何一行或所有一行都可能具有此属性额外的
值,这取决于优化器在确定完整执行计划时的进度。为每个记录检查的范围(索引映射:
(JSON属性:N
)消息
)MySQL发现没有好的索引可以使用,但发现在前面表中的列值已知后,可以使用一些索引。对于上述表中的每个行组合,MySQL检查是否可以使用
范围
或index_merge
Access方法来检索行。这不是很快,但比执行没有索引的连接要快。适用性标准见第8.2.1.2节,“范围优化”,章节8.2.1.3,“索引合并优化”,除了上表的所有列值都是已知的,并被认为是常量。索引从1开始编号,顺序与
显示指数
在桌子上。索引映射值N
位掩码值,指示哪些索引是候选索引。例如,值0 x19
(binary 11001)表示考虑索引1、4和5。扫描
(JSON属性:N
数据库消息
)这表示服务器在处理查询时执行多少目录扫描
INFORMATION_SCHEMA
表,如章节8.2.3,“优化INFORMATION_SCHEMA查询”.的价值N
可以是0、1或所有
.选择优化后的表
(JSON属性:消息
)优化器确定1)最多应该返回一行,2)为了生成这一行,必须读取一组确定的行。如果在优化阶段可以读取要读取的行(例如,通过读取索引行),则在查询执行期间不需要读取任何表。
当查询隐式分组(包含一个聚合函数,但没有
集团
条款)。当对使用的每个索引执行一行查找时,第二个条件就满足了。读取索引的数量决定了要读取的行数。考虑以下隐式分组查询:
SELECT MIN(c1), MIN(c2) FROM t1;
假设
分钟(c1)
可以通过读取一个索引行和分钟(c2)
可以通过从不同的索引中读取一行来检索。也就是说,对于每一列c1
而且c2
,则存在一个索引,其中该列是索引的第一列。在这种情况下,通过读取两个确定的行,返回一行。这
额外的
如果要读取的行不是确定的,则不会发生。考虑这个查询:SELECT MIN(c2) FROM t1 WHERE c1 <= 10;
假设
(c1, c2)
是覆盖指数。使用此索引,包含的所有行C1 <= 10
必须扫描才能找到最小值c2
价值。相比之下,考虑以下查询:SELECT MIN(c2) FROM t1 WHERE c1 = 10;
在本例中,第一个索引行
C1 = 10
包含最小值c2
价值。只需读取一行即可产生返回的行。对于维护每个表的精确行数的存储引擎(例如
MyISAM
,但不是InnoDB
),这额外的
值可以发生在COUNT (*)
的查询在哪里
子句缺失或总是真,没有集团
条款。(这是一个隐式分组查询的实例,其中存储引擎会影响是否可以读取确定数量的行。)Skip_open_table
,Open_frm_only
,Open_full_table
(JSON属性:消息
)这些值指示应用于查询的文件打开优化
INFORMATION_SCHEMA
表,如章节8.2.3,“优化INFORMATION_SCHEMA查询”.Skip_open_table
:表文件不需要打开。通过扫描数据库目录,查询中的信息已经可用。Open_frm_only
只有桌子的.frm
文件需要打开。Open_full_table
:未优化信息查找。的.frm
,.MYD
,.MYI
文件必须打开。
开始临时
,暂时的结束
(JSON属性:消息
)这表明半连接副本清除策略使用临时表。
未找到唯一行
(JSON属性:消息
)对于查询,例如
选择……从
,没有行满足a的条件tbl_name
独特的
索引或主键
在桌子上。使用filesort
(JSON属性:using_filesort
)MySQL必须执行额外的操作,以找出如何按顺序检索行。对象的连接类型遍历所有行,并为匹配的所有行存储排序键和指向该行的指针
在哪里
条款。然后对键进行排序,并按排序顺序检索行。看到第8.2.1.14节,“优化排序”.使用索引
(JSON属性:using_index
)只使用索引树中的信息从表中检索列信息,而不需要执行额外的查找操作来读取实际行。当查询仅使用作为单个索引一部分的列时,可以使用此策略。
为
InnoDB
具有用户定义的聚集索引的表,即使在以下情况下也可以使用该索引使用索引
缺席了额外的
列。这是如果的情况类型
是指数
而且关键
是主要的
.使用索引条件
(JSON属性:using_index_condition
)读取表的方法是访问索引元组并首先测试它们,以确定是否读取完整的表行。通过这种方式,索引信息被用于延迟(”下推”)读取完整的表行,除非有必要。看到章节8.2.1.5,“索引条件下推优化”.
使用index进行分组
(JSON属性:using_index_for_group_by
)类似于
使用索引
表访问方法,使用index进行分组
表示MySQL找到了一个索引,可以用来检索a的所有列集团
或截然不同的
查询时不需要对实际表进行任何额外的磁盘访问。此外,以最有效的方式使用索引,因此对于每个组,只读取少数索引项。详细信息请参见第8.2.1.15节,“优化分组”.使用连接缓冲区(块嵌套循环)
,使用连接缓冲区(批量密钥访问)
(JSON属性:using_join_buffer
)早期连接中的表部分读入连接缓冲区,然后从缓冲区中使用它们的行来执行与当前表的连接。
(块嵌套循环)
表示使用块嵌套循环算法和(匙匙批接)
表示使用批量密钥访问算法。的前一行表中的键解释
输出被缓冲,匹配的行从表中批量提取使用连接缓冲区
出现了。在json格式输出中,的值
using_join_buffer
总是其中之一吗块嵌套循环
或批量密钥访问
.使用MRR
(JSON属性:消息
)使用Multi-Range read优化策略读取表。看到第8.2.1.10节“多范围读优化”.
使用sort_union(…)
,使用联盟(…)
,使用相交(…)
(JSON属性:消息
)属性的索引扫描合并的特定算法
index_merge
连接类型。看到章节8.2.1.3,“索引合并优化”.使用临时
(JSON属性:using_temporary_table
)要解析查询,MySQL需要创建一个临时表来保存结果。如果查询包含
集团
而且命令
以不同方式列出列的子句。使用在哪里
(JSON属性:attached_condition
)一个
在哪里
子句用于限制哪些行与下一个表匹配或发送到客户端。方法获取或检查表中的所有行,否则查询中可能出现错误额外的
价值不是使用在哪里
表连接类型为所有
或指数
.使用在哪里
在json格式的输出中没有直接对应的内容;的attached_condition
属性包含在哪里
使用条件。使用where和push条件
(JSON属性:消息
)本条款适用于
NDB
表只有.这意味着NDB集群正在使用条件下推优化来提高非索引列和常量之间直接比较的效率。在这种情况下,条件是”下推”发送到集群的数据节点,并在所有数据节点上同时计算。这样就不需要通过网络发送不匹配的行,并且可以将这种查询速度提高5到10倍,而不是使用Condition Pushdown。有关更多信息,请参见章节8.2.1.4“发动机状态下压优化”.零极限
(JSON属性:消息
)这个问题有一个
极限0
子句且不能选择任何行。
方法中的值的乘积可以很好地指示一个连接有多好行
的列解释
输出。这将大致告诉您MySQL必须检查多少行才能执行查询。方法限制查询max_join_size
系统变量,这个行积也是用来确定哪个多表的选择
要执行的语句和要中止的语句。看到第5.1.1节“配置服务器”.
下面的示例显示如何根据所提供的信息逐步优化多表连接解释
.
解释选择tt。TicketNumber, tt。TimeIn, tt。ProjectReference, tt。EstimatedShipDate, tt。ActualShipDate, tt。ClientID, tt。ServiceCodes, tt。RepetitiveID, tt。CurrentProcess, tt。CurrentDPPerson, tt。RecordVolume, tt。dpprint, et.COUNTRY, et_1。国家,做。CUSTNAME FROM tt, et, et AS et_1, do WHERE tt。提交时间是NULL和tt。ActualPC=et.EMPLOYID AND tt.AssignedPC = et_1.EMPLOYID AND tt.ClientID = do.CUSTNMBR;
对于这个例子,做以下假设:
正在比较的列声明如下。
表格 列 数据类型 tt
ActualPC
CHAR (10)
tt
AssignedPC
CHAR (10)
tt
ClientID
CHAR (10)
等
EMPLOYID
CHAR (15)
做
CUSTNMBR
CHAR (15)
这些表有以下索引。
表格 指数 tt
ActualPC
tt
AssignedPC
tt
ClientID
等
EMPLOYID
(主键)做
CUSTNMBR
(主键)的
tt。一个ctualPC
数值分布并不均匀。
最初,在执行任何优化之前解释
语句产生以下信息:
表类型possible_keys key key_len ref rows Extra et ALL PRIMARY NULL NULL NULL 74 do ALL PRIMARY NULL NULL NULL NULL 2135 et_1 ALL PRIMARY NULL NULL NULL NULL 74 tt ALL AssignedPC, NULL NULL NULL NULL 3872 ClientID, ActualPC范围检查每条记录(索引映射:0x23)
因为类型
是所有
对于每个表,这个输出表明MySQL正在生成所有表的笛卡尔积;也就是说,每一行的组合。这需要相当长的时间,因为必须检查每个表中行数的乘积。对于手头的例子,这个乘积是74 × 2135 × 74 × 3872 = 45,268,558,720行。如果桌子再大一些,你可以想象需要多长时间。
这里的一个问题是,如果将列声明为相同的类型和大小,MySQL可以更有效地使用列上的索引。在这种情况下,VARCHAR
而且字符
如果它们声明为相同的大小,则被认为是相同的。tt。一个ctualPC
声明为CHAR (10)
而且et.EMPLOYID
是CHAR (15)
,所以长度不匹配。
若要修复列长度之间的差异,请使用ALTER TABLE
延长ActualPC
10 ~ 15个字符:
mysql> ALTER TABLE tt MODIFY ActualPC VARCHAR
现在tt。一个ctualPC
而且et.EMPLOYID
都是VARCHAR (15)
.执行解释
语句再次产生如下结果:
table type possible_keys key key_len ref rows Extra tt ALL AssignedPC, NULL NULL NULL NULL 3872 Using ClientID, where ActualPC do ALL PRIMARY NULL NULL NULL 2135检查每条记录的范围(索引映射:0x1) et_1 ALL PRIMARY NULL NULL NULL 74检查每条记录的范围(索引映射:0x1) et eq_ref PRIMARY PRIMARY 15 tt。ActualPC 1
这不是完美的,但要好得多:的产品行
值是74的1 / 4。这个版本在几秒钟内执行。
属性的列长度不匹配,可以进行第二种更改tt。一个ssignedPC = et_1.EMPLOYID
而且tt。ClientID = do。CUSTNMBR
比较:
mysql> ALTER TABLE tt MODIFY assigndpc VARCHAR(15),修改客户端VARCHAR(15);
在修改之后,解释
产生如下所示的输出:
table type possible_keys key key_len ref rows Extra et ALL PRIMARY NULL NULL NULL 74 tt ref AssignedPC, ActualPC 15 et. employid 52 Using ClientID, where ActualPC et_1 eq_ref PRIMARY PRIMARY 15 tt。assign dpc 1 do eq_ref PRIMARY PRIMARY 15 tt。ClientID 1
此时,查询几乎得到了尽可能好的优化。剩下的问题是,默认情况下,MySQL假设tt。一个ctualPC
列是均匀分布的,而对列则不是这样tt
表格幸运的是,告诉MySQL分析密钥分布是很容易的:
mysql>分析表tt;
有了附加的索引信息,连接就完美了解释
产生如下结果:
table type possible_keys key key_len ref rows Extra tt ALL AssignedPC NULL NULL NULL 3872 Using ClientID, where ActualPC et eq_ref PRIMARY PRIMARY 15 tt。ActualPC 1 et_1 eq_ref PRIMARY PRIMARY 15 tt。assign dpc 1 do eq_ref PRIMARY PRIMARY 15 tt。ClientID 1
的行
列中的解释
是MySQL连接优化器的一个有根据的猜测。检查数字是否接近事实,通过比较行
与查询返回的实际行数的乘积。如果数字相差很大,则可以使用STRAIGHT_JOIN
在你的选择
语句中以不同的顺序列出表从
条款。(然而,STRAIGHT_JOIN
可能阻止使用索引,因为它禁用半连接转换。看到8.2.2.1节,“使用半连接转换优化子查询、派生表和视图引用”.)
在某些情况下,可以执行修改数据的语句解释选择
与子查询一起使用;有关更多信息,请参见第13.2.10.8节,“派生表”.