sql分析工具explain详解

mysql5.7execution-plan文档
explain命令也叫查询执行计划,是根据表、列、索引和WHERE子句中条件的详细信息,MySQL优化器会考虑许多技术来高效执行SQL查询中涉及的查找。可以在不读取所有行的情况下执行对大表的查询;在不比较每个行组合的情况下执行涉及多个表的连接。

使用

使用起来非常简单 explain [yourSql]
explain可以与select、delete、insert、replace和update语句配合使用。因为用来分析select较多,所以接下来就以select来示例。

比如我们要获取以下sql的执行计划

explain
SELECT id, status, uuid, bill_status, plain_data
     , sender, receiver, vin, plan_no, shipment_no
     , base, pub_key_decoder, shipped_date, pub_key_encryptor, enc
     , plan_type, settlement_type, owner_flag
FROM bill_plan
WHERE 1 = 1
  AND sender = 'TestH2'
  AND settlement_type = 'INCOME'
  AND owner_flag = 1
  AND bill_status = 'ssnConfirmed'
  AND base IN ('1','2','3','4','5','6','7')
  AND receiver IN ('Test1','Test2')
ORDER BY id DESC
LIMIT 200;

执行后获取到以下内容
explain执行结构
可以看到输出了很多字段,各个字段的含义分别是:

列名含义
idSELECT标识符
select_typeSELECT类型
table输出行的表
partitions匹配的分区
type连接类型
possible_keys可能的索引可供选择
key实际选择的索引
key_len所选密钥的长度
ref与索引相比的列
rows要检查的行的估计
filtered按表格条件过滤的行百分比
Extra其他信息

字段含义解释

id

这个是sql的序号,没有特殊的含义,可不关注

select_type

select的类型,类型较多

select_type含义
SIMPLE简单SELECT(不使用UNION或子查询)
PRIMARY最外层SELECT
UNION第二个或稍后的SELECT语句UNION
DEPENDENT UNIONUNION中的第二个或稍后SELECT语句,取决于外部查询
UNION RESULTUNION的结果
SUBQUERY子查询中的第一个SELECT
DEPENDENT SUBQUERY子查询中的第一个SELECT,取决于外部查询
DERIVED派生表
MATERIALIZED物质化子查询
UNCACHEABLE SUBQUERY无法缓存结果的子查询,必须为外部查询的每一行重新评估
UNCACHEABLE UNION第二个或稍后在UNION中选择属于不可缓存的子查询

table

查询表名

type

连接类型,我们如果要优化,type至少也要是range级别以上。性能从好到差如下:

类型描述
system该表只有一行(=系统表)。这是const连接类型的特例。
const该表最多有一个匹配的行,在查询开始时读取。因为只有一行,所以该行中列的值可以被优化器的其余部分视为常量。const表非常快,因为它们只读一次。通过PRIMARY KEY或UNIQUE索引用=查询,例SELECT * FROM tbl_name WHERE primary_key=1; 或者 SELECT * FROM tbl_name WHERE primary_key_part1=1 AND primary_key_part2=2;
eq_ref对于上一个表中的每行组合,都会从此表中读取一行。除了system和const类型外,这是最好的连接类型。当连接使用索引的所有部分,并且索引是PRIMARY KEY或UNIQUE NOT NULL索引时它使用的类型。SELECT * FROM ref_table,other_table WHERE ref_table.key_column_part1=other_table.column AND ref_table.key_column_part2=1;
ref对于之前表中的每个行组合,都会从此表中读取所有具有匹配索引值的行。如果连接仅使用键的最左边前缀,或者如果键不是PRIMARY KEY或UNIQUE索引(换句话说,如果连接无法根据键值选择单行),则使用ref如果使用的键只匹配几行,这是一个很好的连接类型。
ref_or_null这个连接类型类似于ref,但是MySQL会对包含NULL值的行进行额外搜索。这种连接类型优化最常用于解析子查询。在下面的例子中,MySQL可以使用ref_or_null连接来处理ref_table:SELECT * FROM ref_table WHERE key_column=expr OR key_column IS NULL;
index_merge此连接类型表示使用了索引合并优化。在这种情况下,输出行中的key列包含所用索引的列表,key_len包含所用索引的最长键部分的列表
unique_subquery此类型替换了以下形式的一些IN子查询的eq_ref:value IN (SELECT primary_key FROM single_table WHERE some_expr)
index_subquery此连接类型类似于unique_subquery。它取代了IN子查询,但它适用于子查询中的非唯一索引
range仅检索给定范围内的行,使用索引选择行。输出行中的key列指示使用哪个索引。key_len包含使用过的最长键部分。此类型的ref列为NULL。range当使用任何=、<>、>、>=、<=、IS NULL、<=>、BETWEEN、LIKE或IN()运算符将键列与常量进行比较时,可以使用:SELECT * FROM tbl_name WHERE key_part1 = 10 AND key_part2 IN (10,20,30);
index当查询仅使用作为单个索引一部分的列时
ALL全表扫描

possible_keys

possible_keys列显示MySQL可以选择使用的索引。请注意,此列与EXPLAIN输出中显示的表格顺序完全无关。这意味着possible_keys中的key与实际使用的不一致。

如果此列为NULL(或在JSON格式的输出中未定义),则没有使用索引或表没有索引。

key

MySQL实际决定使用的索引,不一定是possible_keys中列出的,因为MyISAM会通过运行ANALYZE TABLE来选择更好的索引。

key_len

key_len列表示MySQL决定使用的索引的长度。key_len的值使您能够确定MySQL实际使用的多部分索引的多少部分。如果key列显示NULL,则key_len列也显示NULL。

ref

ref列显示哪些列或常量与key列中命名的索引进行比较,以便从表中选择行。

如果值是func,则使用的值是某个函数的结果。要查看哪个功能,请使用EXPLAIN之后SHOW WARNINGS来查看扩展的EXPLAIN输出。该函数实际上可能是一个运算符,例如算术运算符。

rows

rows表示MySQL认为必须检查才能执行查询的行数。

filtered

filtered列表示按表条件过滤的表行的估计百分比。越高越好
最大值为100,这意味着没有发生行过滤。从100减少的值表示过滤量增加。rows显示检查的估计行数,×filteredrows显示与下表连接的行数。例如,如果rows是1000,filtered是50.00(50%),则与下表连接的行数为1000 × 50% = 500。

Extra

有关MySQL如何解决查询的更多信息

explain分析结果

explain执行结构
根据前面的执行结果和字段说明,我们可以得出结果:

  • 这是一个简单查询(没有join / 子查询)select_type=SIMPLE
  • 单表查询 talbe=bill_plan
  • 连接类型为index,只使用了一部分索引,还可以继续优化type=index
  • mysql可以选择使用的索引为status_bill_status_idx possible_keys=status_bill_status_idx
  • mysql最终决定使用的索引为PRIMARY key=PRIMARY
  • 执行该sql需要检查3312行 rows=3312
  • 检查行中有效数据只有0.6% filtered=0.6
  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQLEXPLAIN语句用于分析和优化查询语句的执行计划。通过执行EXPLAIN语句,你可以了解MySQL是如何处理你的查询,包括表的访问顺序、使用的索引、连接方式等。 下面是使用EXPLAIN语句来优化SQL查询的步骤: 1. 确定要优化的查询语句。可以使用SELECT语句来查询数据,然后在该语句前加上EXPLAIN关键字。例如:EXPLAIN SELECT * FROM table_name WHERE condition; 2. 执行EXPLAIN语句,并查看结果。执行EXPLAIN后,MySQL会返回一张表格,其中包含了查询的执行计划信息。这些信息可以帮助你分析查询的性能瓶颈。 3. 分析执行计划信息。在执行计划信息表格中,你可以关注以下几个重要的列: - id: 查询的唯一标识符。多表查询时,每个表都有一个唯一标识符。 - select_type: 查询类型。包括简单查询、联接查询、子查询等。 - table: 查询涉及的表名。 - type: 表示MySQL访问表的方式,常见的有ALL、index、range、ref等。 - possible_keys: 表示可能使用的索引。 - key: 实际使用的索引。 - rows: 估计扫描的行数。 - Extra: 额外的信息,如是否使用了临时表、是否使用了文件排序等。 4. 根据执行计划信息来进行优化。根据查询的复杂性和性能要求,你可以采取以下一些优化措施: - 确保表中的列上有适当的索引。 - 使用JOIN语句时,确保连接条件上有索引。 - 避免在查询中使用通配符(如SELECT *)。 - 尽量减少子查询的使用。 - 优化WHERE条件,尽量避免使用OR、NOT等复杂的逻辑判断。 - 使用合适的数据类型,避免不必要的数据类型转换。 通过不断地执行EXPLAIN语句,分析执行计划信息,并针对性地进行优化,你可以提高查询的性能并减少数据库的负载。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值