mysql:EXPLAIN 和 SHOW WARNINGS一起使用得到实际执行的sql

本文介绍了如何通过结合使用MySQL的EXPLAIN和SHOW WARNINGS命令来查看实际执行的SQL和查询优化过程。在5.7版本及以后,EXPLAIN不再需要EXTENDED选项,可以直接获取优化后的查询计划。示例展示了对于IN子查询的优化,MySQL会将其转换为EXISTS语句,这可能导致性能问题。通过这种方式,开发者可以更深入地理解查询优化并进行性能调优。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

mysql:EXPLAIN 和 SHOW WARNINGS一起使用得到实际执行的sql

之前写一个where in子查询,看到了这一篇深入理解MySql子查询IN的执行和优化文章,里面提到了这一句,让我觉得很有趣

通过EXPLAIN EXTENDED 和 SHOW WARNINGS命令,看到如下结果:

select northwind.driver.driver_id AS driver_id from northwind.driver where <in_optimizer>(northwind.driver.driver_id,(select 1 from northwind.user where ((northwind.user.uid = northwind.driver.driver_id) and ((northwind.driver.driver_id) = northwind.driver.driver_id))))

可以看出无论是独立子查询还是相关子查询,MySql 5.5之前的优化器都是将IN转换成EXISTS语句。如果子查询和外部查询分别返回M和N行,那么该子查询被扫描为O(N+N*M),而不是O(N+M)。这也就是为什么IN慢的原因。

很好,我虽然之前大量使用explain调优,但是还是第一次知道这一种用法特地查了一下

The EXPLAIN statement produces extra (“extended”) information that is not part of EXPLAIN output but can be viewed by issuing a SHOW WARNINGS statement following EXPLAIN.

官方原文说法是说explain 可以给出额外的解释,但是需要 SHOW WARNINGS使用. 注意不同版本的mysql这样的使用可能有不一致.我看到有的博客说explain extended会多一个fliter,我查了一下,在我的版本(5.7)中并没有这个.文档里面就说在5.7之后不再需要extended,这个词了,直接使用就可以得到实际上优化器优化后的sql.

这里我试了一下,要注意这两个要接在一起.

mysql> EXPLAIN
SELECT t1.a, t1.a IN (SELECT t2.a FROM t2) FROM t1\G
*************************** 1. row ***************************
id: 1
select_type: PRIMARY
table: t1
type: index
possible_keys: NULL
key: PRIMARY
key_len: 4
ref: NULL
rows: 4
filtered: 100.00
Extra: Using index
*************************** 2. row ***************************
id: 2
select_type: SUBQUERY
table: t2
type: index
possible_keys: a
key: a
key_len: 5
ref: NULL
rows: 3
filtered: 100.00
Extra: Using index
2 rows in set, 1 warning (0.00 sec)

mysql> SHOW WARNINGS\G
*************************** 1. row ***************************
Level: Note
Code: 1003
Message: /* select#1 / select test.t1.a AS a,
<in_optimizer>(test.t1.a,test.t1.a in
( (/
select#2 */ select test.t2.a
from test.t2 where 1 having 1 ),
<primary_index_lookup>(test.t1.a in
on <auto_key>
where ((test.t1.a = materialized-subquery.a))))) AS t1.a IN (SELECT t2.a FROM t2) from test.t1
1 row in set (0.00 sec)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值