使用 EXPLAIN 命令可以展示出当前优化器所生成的执行计划,但由于统计信息变化、用户 session 变量设置变化等,会造成该 SQL 在计划缓存中实际对应的计划可能与 EXPLAIN 的结果并不相同。为了确定该 SQL 在系统中实际使用的执行计划,需要进一步分析计划缓存中的物理执行计划。

用户可以通过查询 (g)v$plan_cache_plan_explain 视图来展示某条 SQL 在计划缓存中的执行计划。

如下例所示:

  1. obclient>VIEW_DEFINITION='SELECT *
  2. FROM oceanbase.gv$plan_cache_plan_explain
  3. WHERE IP =host_ip() AND PORT = rpc_port()'

参数解释如下表:

字段名称

类型

描述

TENANT_ID

bigint(20)

租户 ID

IP

varchar(32)

IP 地址

PORT

bigint(20)

端口号

PLAN_ID

bigint(20)

执行计划的 ID

OPERATOR

varchar(128)

operator 的名称

NAME

varchar(128)

表的名称

ROWS

bigint(20)

预估的结果行数

COST

bigint(20)

预估的代价

PROPERTY

varchar(256)

对应 operator 的信息

第一步 查询 SQL 在计划缓存中的 plan_id

OceanBase 数据库每个服务器的计划缓存都是独立的。用户可以直接访问 v$plan_cache_plan_stat 视图查询本服务器上的计划缓存并提供 tenant_id 和需要查询的 SQL 字符串(可以使用模糊匹配),查询该条 SQL 在计划缓存中对应的 plan_id。

  1. obclient>SELECT * FROM v$plan_cache_plan_stat WHERE tenant_id= 1001
  2. AND STATEMENT LIKE 'INSERT INTO T1 VALUES%'\G
  3. ***************************1. row ***************************
  4. tenant_id: 1001
  5. svr_ip:100.81.152.44
  6. svr_port:15212
  7. plan_id: 7
  8. sql_id:0
  9. type: 1
  10. statement: insert into t1 values(1)
  11. plan_hash:1
  12. last_active_time:2016-05-28 19:08:57.416670
  13. avg_exe_usec:0
  14. slowest_exe_time:1970-01-01 08:00:00.000000
  15. slowest_exe_usec:0
  16. slow_count:0
  17. hit_count:0
  18. mem_used:8192
  19. 1 rowin set (0.01 sec)

第二步 使用 plan_id 展示对应执行计划

获得 plan_id 后,用户可以使用 tenant_id 和 plan_id 访问 v$plan_cache_plan_explain 来展示该执行计划。

注意

这里展示的计划为物理执行计划,在算子命名上会与 EXPLAIN 所展示的逻辑执行计划有所不同。

  1. obclient>SELECT * FROM v$plan_cache_plan_explain
  2. WHERE tenant_id = 1001 AND plan_id = 7;
  3. +-----------+---------------+-------+---------+--------------------+------+------+------+
  4. | TENANT_ID | IP | PORT | PLAN_ID | OPERATOR | NAME | ROWS | COST |
  5. +-----------+---------------+-------+---------+--------------------+------+------+------+
  6. | 1001 | 100.81.152.44 | 15212 | 7 | PHY_ROOT_TRANSMIT | NULL | 0 | 0 |
  7. | 1001 | 100.81.152.44 | 15212 | 7 | PHY_INSERT | NULL | 0 | 0 |
  8. | 1001 | 100.81.152.44 | 15212 | 7 | PHY_EXPR_VALUES | NULL | 0 | 0 |
  9. +-----------+---------------+-------+---------+--------------------+------+------+------+
  10. 3 rows in set (0.01 sec)

注意

  • 如果访问 gv$plan_cache_plan_explain,必须给定 IP、port、tenant_id 和 plan_id 这四列的值。

  • 如果访问 v$plan_cache_plan_explain,必须给定 tenant_id 和 plan_id 的值,否则系统将返回空集。