如何使用EXPLAIN分析SQL执行计划?

如何使用EXPLAIN分析SQL执行计划?

2 个赞

在 OceanBase 中,使用 EXPLAIN 命令查看 SQL 的执行计划是进行 SQL 性能分析和优化的先决条件34。以下是具体的使用方法和分析步骤:

1. 使用不同的 EXPLAIN 模式获取执行计划

OceanBase 提供了多种 EXPLAIN 模式,以适应不同粒度的分析需求:

  • 基础执行计划 (EXPLAIN ) :展示执行计划的基本信息,帮助普通用户了解整个计划的执行方式23。
  • 详细执行计划 (EXPLAIN EXTENDED ) :展示最详细的执行计划,包括表的扫描范围等,通常在排查复杂问题时使用34。
  • 基本执行计划 (EXPLAIN BASIC ) :用于最基本的计划展示,信息较为精简23。
  • JSON 格式输出 (EXPLAIN FORMAT = JSON ) :以 JSON 格式展示执行计划,适合进行复杂分析或程序解析。

2. 解读执行计划中的关键信息

获取执行计划后,需要重点关注输出结果中的 OPERATORNAME 列来判断 SQL 的执行逻辑:

  • 查看 OPERATOR
    • 如果显示 TABLE SCAN ,表示没有走索引,正在进行全表扫描6。
    • 如果显示 INDEX SCANINDEX SEEK ,表示查询成功走了索引。
    • 如果显示 TABLE GET ,通常表示通过主键进行等值访问,也属于高效的索引访问方式。
  • 查看 NAME
    • 如果仅显示表名或别名(如 users(t1) ),通常对应全表扫描。
    • 如果显示 表名(别名)索引名 (如 users(u),idx_user_id ),则明确表示使用了指定的索引。

3. 排查未走索引的常见原因

如果发现 SQL 没有走预期的索引,可以通过以下步骤进行排查:

  • 检查索引定义 :确认表上是否存在相关的索引(可使用 SHOW INDEX FROM 表名; )。
  • 检查查询条件匹配度 :例如联合索引是 (a, b) ,但查询条件只使用了 b ,则无法命中索引。
  • 检查隐式类型转换或函数使用 :在索引列上使用函数(如 WHERE UPPER(name) = 'ABC' )或在字符串列上使用数字查询(如 WHERE id = '123' ),都可能导致索引失效。
  • 检查统计信息 :如果怀疑优化器因为统计信息过时做出了错误决策,可以手动收集统计信息(如 ANALYZE TABLE 表名 UPDATE STATISTICS; )6。
2 个赞

查看语句的逻辑执行计划

1 个赞

very good

在 OceanBase 中,EXPLAIN 是分析 SQL 执行计划的核心工具。它能告诉你数据库会如何执行这条 SQL,比如用了哪些索引、表之间的连接顺序、以及每步的数据处理方式。

用好 EXPLAIN,是进行 SQL 调优的基本功。下面一步步来看。


第一步:基本用法

1. 查看基础执行计划

直接在 SQL 前加 EXPLAIN 即可,OceanBase 默认输出是树形文本格式(缩进代表层级):

EXPLAIN SELECT * FROM t1 WHERE id = 1;

2. 获取更详细的信息(推荐)

EXPLAIN EXTENDEDEXPLAIN 加 Hint,能看到更多优化器决策细节:

-- 查看详细计划(包括每步的谓词、表达式等)
EXPLAIN EXTENDED SELECT * FROM t1 WHERE id = 1;

-- 使用 Outline Hint 方式查看(更贴近真实执行)
EXPLAIN SELECT /*+ outline */ * FROM t1 WHERE id = 1;

第二步:读懂执行计划(关键输出字段)

执行计划会以操作符(Operator)树的形式呈现。你通常会在输出里看到这些核心信息:

关键部分 含义 举例
ID 操作符的执行序号,从0开始,数字越大越先执行(即最内层先执行) ID 2 会比 ID 1 先执行
OPERATOR 具体的操作类型,如 TABLE SCANNESTED-LOOP JOINSORT TABLE SCAN(全表扫描)或 TABLE GET(主键点查)
NAME 操作的对象,通常是表名或索引名 t1t1_idx1
EST. ROWS 优化器估算的该步返回的行数(用于判断估算是否准确) 100
COST 优化器估算的该步执行代价(数值越小通常越快) 152.3

示例输出:

| ========================================
| ID | OPERATOR    | NAME | EST. ROWS | COST |
| ---|-------------|------|-----------|------|
| 0  | TABLE SCAN  | t1   | 1         | 12.5 |
| ========================================

第三步:常见操作符解读

看懂操作符,你就知道 SQL 的大致执行路径了:

  • TABLE GET:通过主键精准获取一行,效率极高,是最理想的点查。
  • TABLE SCAN:全表扫描,意味着要读取表中所有数据,通常效率较低(除非小表)。
  • INDEX SCAN:扫描索引表,能避免回表(索引包含所需字段)时效率很高。
  • NESTED-LOOP JOIN:嵌套循环连接,适用于驱动表很小或被驱动表有索引的场景。
  • HASH JOIN:哈希连接,适用于大表关联且无合适索引的场景,会消耗内存。
  • MERGE JOIN:归并连接,连接键已有序时使用。
  • SORT:显式排序操作,若数据量大可能产生磁盘落盘,较耗资源。

第四步:查看真实执行信息(与 EXPLAIN 区分)

EXPLAIN 只是预估,要查看 SQL 真实执行的统计信息(如实际扫描行数、耗时),需要用:

-- 先开启会话级统计信息收集(只需执行一次)
SET SESSION ob_enable_trace_log = ON;

-- 执行你的 SQL
SELECT * FROM t1 WHERE id = 1;

-- 查看真实执行统计信息(重点关注物理读、扫描行数)
SHOW TRACE;

对比 EXPLAIN 估算的 EST. ROWSSHOW TRACE 里的实际扫描行数,是发现统计信息过期(导致选错计划)的常见方法。