欢迎关注公众号(通过文章导读关注:【11来了】),及时收到 AI 前沿项目工具及新技术的推送!
在我后台回复 「资料」 可领取
编程高频电子书
!
在我后台回复「面试」可领取硬核面试笔记
!文章导读地址:点击查看文章导读!
感谢你的关注!
通过实操理解 explain 执行计划
- 案例一:开胃小菜
SQL 语句:
explain select * from test1;
执行计划如下:
首先,id = 1,id 是每一个 SQL 语句的唯一标识
select_type 值为 SIMPLE 表示这个 SQL 是一个简单的查询,不包含子查询以及 union 等操作
table 表明对哪个表进行的操作
type = index 表明对二级索引的叶子节点进行扫描得到了结果,因为这个 test1 表里只有两个字段,id 和 name,我在 name 列上建立了索引,因此对 name 索引的叶子节点扫描一遍就可以得到 id 和 name 值
rows = 3 表明扫描了 3 行数据
filtered = 100 表明没有通过 where 过滤数据,因此筛选出来的数据在表里数据的占比为 100%
- 案例二:多表查询
SQL 语句:
explain select * from test1 join test2;
执行计划:
可以发现有两条执行计划,也就是说明会访问两个表,两条执行计划的 id 都是 1,说明是同一个 SQL 语句
首先第一条执行计划是对 test2 表进行全表扫描(type = ALL),rows = 1 表明扫描出来了 1 条数据,在表中占比为 100%
第二条执行计划是对 test1 表进行全表扫描,rows = 3 表明扫描出来 3 条数据,占比 100%,其中 Extra 列与第一条执行计划有所不同
可以看到 Extra 列值为 Using join buffer(Block Nested Loop)
,
这是因为使用了 join 对两个表进行连表查询,这样其实查出来的是笛卡尔积,对两个表中的所有数据进行关联,在 MySQL 中一般会以数据量比较小的表作为驱动表,因此以 test2 表为驱动表,去 test1 表中找到所有数据进行匹配,小表作为驱动表可以减少比较的行数,在 test1 表中对数据进行匹配时使用到了 Using join buffer,也就是通过一块内存区域 join buffer 来对数据进行连接操作,而 Nested Loop 表明进行嵌套循环连接,也就是笛卡尔积(test2 表的每一行数据都和 test1 表的每行数据做连接)
- 案例三:union 并集查询
SQL 语句:
explain select * from test1 union select * from test2;
执行计划:
前两条执行计划就是对 test1 和 test2 这两张表进行全表扫描操作
第 3 条执行计划是对两张表中的数据进行合并去重操作,table = <union 1,2>
指的是这个临时表的表名,extra = Using temporary
也表明了使用了临时表
union
是对两张表的结果进行合并去重
union all
的话不会对数据进行去重操作