MySQL-extra常见的额外信息

在这里插入图片描述

本文为大家介绍MySQL查看执行计划时,extra常见的额外信息

Using index

表示使用了覆盖索引,即通过索引树可以直接获取数据,不需要回表。

表结构:
CREATE TABLE `t1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `age` int(10) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`) USING BTREE
) ENGINE=InnoDB 

复现SQL

select id from t1 where id=1;

select name from t1 where name=‘aaa’;

select id from t1 where name=‘aaa’;

Using where

使用了where查询,但是条件字段上没有索引

表结构:
CREATE TABLE `t1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `age` int(10) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`) USING BTREE
) ENGINE=InnoDB 

复现SQL

select name from t1 where age=11;

select * from t1 where age=11;

Using temporary

查询过程中需要使用临时表做为中间结果集

表结构:
CREATE TABLE `t1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `age` int(10) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`) USING BTREE
) ENGINE=InnoDB
---------------------------------------------
CREATE TABLE `t2` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `age` int(10) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB

复现SQL

select a.* from t1 as a LEFT JOIN t2 as b on a.id=b.id order by b.age desc ;

with tmp as (select name from t2)
select * from t1 where name in (select * from tmp);

Using filesort

查询中使用了排序,同时排序没有直接使用索引

表结构:
CREATE TABLE `t1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`) USING BTREE
) ENGINE=InnoDB 

复现SQL

select name from t1 ORDER BY age;

select * from t1 ORDER BY name;

Using join buffer (Block Nested Loop)

关联查询时使用了块嵌套循环连接

表结构
CREATE TABLE `t1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `age` int(10) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`) USING BTREE
) ENGINE=InnoDB 
-------------------------------------------------------
CREATE TABLE `t2` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `age` int(10) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`) USING BTREE
) ENGINE=InnoDB 

复现SQL

select a.* from t1 as a left JOIN t2 as b on a.age=b.age ;

select * from t1 as a left JOIN t2 as b on a.name=b.name ;

Impossible where

查询时where的条件不可能为真,所以将返回空结果集

表结构
CREATE TABLE `t1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `age` int(10) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`) USING BTREE
) ENGINE=InnoDB

复现SQL

select * from t1 where 1=2;

Select tables optimized away

查询时某些表没有被使用,从而被优化掉

表结构
CREATE TABLE `t1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `age` int(10) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`) USING BTREE
) ENGINE=InnoDB

复现SQL

select max(id) from t1;

select min(name) from t1;

Using index condition

使用了索引范围扫描,且需要回表

表结构
CREATE TABLE `t1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `age` int(10) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`) USING BTREE
) ENGINE=InnoDB

复现SQL

select * from t1 where name>‘aaa’;

LooseScan\FirstMatch(tbl_name)

将In子查询转为semi-join时,如果采用的是LooseScan执行策略,则在驱动表执行计划的Extra列就是显示LooseScan提示
将In子查询转为semi-join时,如果采用的是FirstMatch执行策略,则在被驱动表执行计划的Extra列就是显示FirstMatch(tbl_name)提示

表结构
CREATE TABLE `t1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `age` int(10) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`) USING BTREE
) ENGINE=InnoDB
-----------------------------------------------------------
CREATE TABLE `t2` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `age` int(10) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`) USING BTREE
) ENGINE=InnoDB

复现SQL

当t2中数据量较多时
select * from t1 where name in (select name from t2)
FirstMatch(t1)

当t2中数据量较少时
select * from t1 where name in (select name from t2)
LooseScan

其实这两个情况的不同是因为优化器判断全扫描out_tables和inner_tables哪个代价更小来决定具体使用哪个策略

彩蛋

优化器的执行流程实际是通过层层计算每个表的最佳访问路径来决定的,如果找到更优的执行计划则更新,否则优化结束。简单的说就是“动态规划+贪心算法”的过程

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值