EXPLAIN 用法详解(表格)

SQL 执行慢?慢在哪里?EXPLAIN 能做什么? —— 它可以预估执行计划,而不是执行 SQL 本身。EXPLAIN 的意义:了解优化器是怎么走表的

1、基础语法,EXPLAIN怎么写

EXPLAIN SELECT * FROM user WHERE id = 1;
  • EXPLAIN EXTENDED——这是 EXPLAIN 的加强版,除了给出基本的执行计划,还会显示优化器实际执行时是怎么改写你的 SQL 的

  • EXPLAIN FORMAT=JSON——这个是 EXPLAINJSON 格式输出,比传统表格输出更全面,信息更细节,适合程序自动解析或更细粒度分析。

  • EXPLAIN ANALYZE——这是 MySQL 8.0 的“加强版 EXPLAIN”,它会 真正执行语句,并且把真实执行的时间、行数、CPU 使用情况也一起打印出来。

2、重点列含义解析

列名含义常见值典型用法
id查询中执行步骤的序号数字,越大越先执行id 大优先
select_type查询类型SIMPLE, PRIMARY, SUBQUERY是否子查询、派生表
table当前访问的表表名或派生表别名哪个表
partitions分区信息NULL 或分区名用于分区表
type连接类型ALL, index, range, ref, eq_ref越往下性能越好
possible_keys可能用到的索引索引名这里有索引未必用
key实际使用的索引索引名用了哪个索引
key_len使用的索引长度字节数判断是否用上了组合索引
ref哪个列或常数用于索引查找列名、const用什么条件去匹配索引
rows预估扫描行数数字越少越好
filtered过滤后留下的百分比百分数新版本有
Extra额外信息Using filesort, Using temporary关键要看有没有可优化的操作

 3、常见的Extra信息解读:

  • Using index
  • 表示这条查询只用到了索引中的数据,不需要回表去取原表里的行。也叫 覆盖索引扫描(Covering Index Scan)。一般是因为 SELECT 的列都包含在索引里。
  • 实质:只从索引就能拿到需要的列,省掉了去表里再查一趟,I/O 更少,性能好。

  • Using where
  • 表示即使用了索引,也需要再做一次 WHERE 条件过滤,因为索引只定位到了范围,还要额外检查行是否满足条件。
  • SELECT * FROM user WHERE age > 20;
    
  • 如果 age 有索引,那么先用索引定位范围,但大于号范围可能会多扫一些数据,需要后面再筛一遍。

  • Using filesort
  • 表示查询结果需要做 额外排序,而不是直接用索引顺序返回。“filesort” 并不一定是用文件,而是 MySQL 的术语,意思是要在内存里或磁盘里做排序操作。
  • 大表 ORDER BY 没有合适的索引时容易触发,可能会产生大量磁盘临时文件,导致慢。

  • Using temporary
  • 表示执行这条 SQL 时需要用到 临时表 来存放中间结果。常见于 GROUP BYDISTINCTUNION、有子查询的复杂 ORDER BY 等场景。
  • 代价是内存放不下就会写磁盘,慢且占 IO。

  • Impossible WHERE
  • 表示 WHERE 条件永远为假,这条语句根本不会返回数据。通常是写错了条件或者逻辑冲突,比如:
  • SELECT * FROM user WHERE 1 = 0;
    或者
    SELECT * FROM user WHERE id < 1 AND id > 10;
    
  • 有时候是调试 OK,有时候是写错条件了要赶紧排查。

  • Using join buffer
  • 表示执行 JOIN 时,某个表没有走索引,只能用 块嵌套循环 来做匹配。MySQL 会把驱动表(外表)中的行放到一个 join buffer(内存块)里,然后一条条对比匹配内表。
  • 常见于被 JOIN 的表没有合适的索引,导致全表扫描做匹配。通常会让 EXPLAIN 里的 type 看到 ALL(全表扫)。
  • 后果就是块读性能远不如索引匹配,特别是大表 JOIN 时很耗时。

### Oracle 数据库中 EXPLAIN PLAN 命令详解 #### 一、EXPLAIN PLAN 的基本概念 `EXPLAIN PLAN` 是一种用于显示 SQL 查询执行计划的工具。通过该命令可以查看优化器如何处理查询,包括访问路径的选择以及表连接顺序等重要信息[^1]。 #### 二、创建并使用 PLANTABLE 为了能够存储和展示执行计划,在运行 `EXPLAIN PLAN`之前通常需要先建立一个名为 `PLAN_TABLE` 的表来保存这些数据。如果尚未创建此表格,则可以通过如下方式完成: ```sql @?/rdbms/admin/utlxplan.sql; ``` 这条语句会调用脚本来自动构建所需的结构化查询语言(SQL)表单[^2]。 #### 三、获取当前缓存中的执行计划 对于已经存在于共享池内的SQL语句, 可以直接利用DBMS_XPLAN包下的DISPLAY函数来提取其对应的执行方案: ```sql SELECT plan_table_output FROM TABLE(DBMS_XPLAN.DISPLAY('PLAN_TABLE')); ``` 上述代码片段展示了从默认位置读取最近一次分析的结果,并将其格式化输出给用户查阅。 #### 四、刷新共享池注意事项 需要注意的是,在某些情况下可能希望清除内存里的旧有定义以便重新评估新的查询效率。此时可考虑采用以下指令: ```sql ALTER SYSTEM FLUSH SHARED_POOL; ``` 但是请注意这一步骤仅限于测试环境中操作,切勿轻易应用于实际业务场景以免造成不必要的影响。 #### 五、基于 AWR 报告获取历史执行计划 除了即时性的诊断外,管理员也可以借助自动化工作负载资料库(Automated Workload Repository,AWR) 来回顾过往一段时间内特定ID关联起来的历史记录: ```sql select * from table(dbms_xplan.display_awr('${SQL_ID}')); ``` 这里 `${SQL_ID}` 应替换为目标查询的实际编号,从而精确检索到相应的档案详情[^3]。 #### 六、理解常见访问方法 当涉及到具有唯一约束条件的数据列时——无论是作为主键还是设置了UNIQUE索引的情况之下——Oracle倾向于采取高效能的独特扫描策略来进行匹配查找作业[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值