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哪个代价更小来决定具体使用哪个策略

彩蛋

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

在这里插入图片描述

  • 14
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL的EXPLAIN命令可以用于分析查询语句的执行计划,其中包含的EXTRA列提供了关于查询优化器的额外信息。下面是一些常见EXTRA内容解释: 1. Using index:表示查询使用了覆盖索引,即查询结果可以直接从索引中获取,而不需要从数据表中读取数据。 2. Using where:表示查询在执行时使用了WHERE子句中指定的条件。 3. Using temporary:表示查询需要创建一个临时表来处理结果集,这通常是由于GROUP BY、ORDER BY或UNION操作导致的。 4. Using filesort:表示查询需要对结果集进行排序,但无法使用索引完成排序,因此需要创建一个临时表,并进行文件排序。 5. Range checked for each record:表示查询使用了索引范围扫描,即索引扫描的不是整个索引,而是一部分。 6. Using join buffer:表示查询使用了连接缓冲区,这使得MySQL可以更有效地处理连接操作。 7. Impossible where:表示WHERE子句中指定的条件是不可能为真的,因此查询将返回空结果集。 8. Select tables optimized away:表示查询的优化器已经优化了查询,因此不需要访问任何表。 9. Distinct:表示查询使用了DISTINCT关键字,这将导致MySQL对结果集进行去重操作。 10. Fulltext search:表示查询使用了全文搜索,这需要使用全文索引和相关算法来处理。 这些EXTRA内容提供了关于查询优化器如何执行查询的详细信息,可以帮助我们更好地理解查询的执行计划,从而优化查询性能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值