Explain

使用方法

explain sql语句

image-20210805090124307

EXPLAIN SELECT * FROM department;

创建 customer 表,SQL 如下

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for customer
-- ----------------------------
DROP TABLE IF EXISTS `customer`;
CREATE TABLE `customer`  (
  `id` int(11) NOT NULL,
  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of customer
-- ----------------------------
INSERT INTO `customer` VALUES (1, 'zs');

SET FOREIGN_KEY_CHECKS = 1;

分析包含信息

id

  • select 查询的序列号
  • 包含一组数字,表示查询中执行 select 子句或操作表的顺序

值的三种情况

id 相同

EXPLAIN SELECT
	* 
FROM
	employee e,
	department d,
	customer c 
WHERE
	e.dep_id = d.id
	AND e.cus_id = c.id;

image-20210805093755746

执行顺序由上到下

id 不同

EXPLAIN SELECT * FROM department WHERE id = ( SELECT id FROM employee WHERE id =( SELECT id FROM customer WHERE id = 1 ));

image-20210805095145188

如果是子查询,id 的序号会递增,id 值越大优先级越高,优先会被执行

id 相同与不同,同时存在

  • 可以认为是一组,从上往下的顺序执行
  • 在所有组中,id 值越大,优先级越高,越先执行
  • deriverd 衍生出来的虚表
EXPLAIN SELECT
	* 
FROM
	department d,
	( SELECT * FROM employee GROUP BY dep_id ) t 
WHERE
	d.id = t.dep_id;

image-20210805095122392

总结

  • id 值相同,按照顺序走
  • id 值不同,看谁大,就谁先执行
  • id 值大的先执行

select_type

作用:查询类型,主要用于区别普通查询,联合查询,子查询等复杂查询,结果值如下

SIMPLE

  • 简单 select 查询,查询中不包含子查询或者 UNION

PRIMARY

  • 查询中若包含任何复杂的子查询,最外层查询则被标记为 primary

image-20210805101150321

SUBQUERY

  • 在 select 或 where 中包含了子查询

image-20210805101315729

DERIVED

  • 在 from 列表中包含的子查询被标记为 derived(衍生)
  • 把结果放在临时表当中

image-20210805101515657

UNION

  • 若第二个 select 出现在 union 之后,则被标记为 union
EXPLAIN SELECT * FROM employee e LEFT JOIN department d ON e.dep_id = d.id
UNION
SELECT * FROM employee e RIGHT JOIN department d ON e.dep_id = d.id;

image-20210805102245746

  • union 包含在 from 子句的子查询中,外层 select 将被标记为 derived
EXPLAIN SELECT
	* 
FROM
	( SELECT * FROM employee UNION SELECT * FROM employee ) a

image-20210806091722791

UNION RESULT

  • 从 union 表获取结果 select
  • 两个 UNION 合并的结果集在最后

image-20210805101913854

table

  • 显示这一行的数据是关于哪张表的

partitions

  • 如果查询是基于分区表的话,会显示查询访问的分区

type

  • 访问类型排列
  • 结果值最好到最差,如下所示

system

  • 表中有一行记录 (系统表) 这是 const 类型的特例,平时不会出现

const

  • 表示通过索引一次就找到了
  • const 用于比较 primary 或者 unique 索引,直接查询主键或者唯一索引
  • 因为只匹配一行数据,所以很快

image-20210805132929932

eq_ref

  • 唯一性索引扫描
  • 对于每个索引键,表中只有一条记录与之匹配
  • 常见于主键或唯一索引扫描

image-20210805133606572

ref

  • 非唯一性索引扫描,返回匹配某个单独值的所有行
  • 本质上也是一种索引访问
  • 它返回所有匹配某个单独值的行
  • 可能会找到多个符合条件的行
  • 所以它应该属于查找和扫描的混合体

修改 employee 表,添加一个外键,然后在运行如下 SQL 即可出现 ref

image-20210805134526783

EXPLAIN SELECT employee.dep_id, department.id FROM employee, department WHERE employee.dep_id = department.id;

image-20210805134329790

range

  • 只检索给定范围的行,使用一个索引来选择行
  • key 列显示使用了哪个索引
  • 一般就是在你的 where 语句中出现 between<>in 等查询
  • 这种范围扫描索引比全表扫描要好
  • 因为它只需要开始于索引的某一点,而结束于另一点
  • 不用扫描全部索引
EXPLAIN SELECT * FROM employee WHERE id BETWEEN 1 AND 3;

image-20210805135017212

index

  • Full Index Scan
  • indexAll 区别为 index 类型只遍历索引树,通常比 All 要快,因为索引文件通常比数据文件要小
  • all 和 index 都是读全表,但 index 是从索引中读取,all 是从硬盘当中读取
EXPLAIN SELECT id FROM employee;

image-20210805135346049

ALL

  • 将全表进行扫描,从硬盘当中读取数据
  • 如果出现了 All 切数据量非常大,一定要去做优化
EXPLAIN SELECT * FROM employee;

image-20210805135541363

🐤type 要求

  • 一般来说,保证查询至少达到 range 级别
  • 最好能达到 ref
posted @   BNTang  阅读(300)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示