使用 explain 命令,可以展示出当前优化器所生成的执行计划,但由于统计信息变化、用户 session 变量设置变化等,会造成该 SQL 在计划缓存中实际对应的计划可能与 explain 的结果并不相同。为了确定该 SQL 在系统中实际使用的执行计划,需要进一步分析计划缓存中的物理执行计划。
用户可以通过查询 (g)v$plan_cache_plan_explain 虚拟表来展示某条 SQL 在计划缓存中的执行计划。
如下例所示:
view_definition='SELECT *
FROM oceanbase.gv$plan_cache_plan_explain
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。
OceanBase(root@oceanbase)>select *
from v$plan_cache_plan_stat
where tenant_id= 1001
and statement like 'insert into t1 values%'\G
***************************1. row ***************************
tenant_id: 1001
svr_ip:100.81.152.44
svr_port:15212
plan_id: 7
sql_id:0
type: 1
statement: insert into t1 values(1)
plan_hash:1
last_active_time:2016-05-28 19:08:57.416670
avg_exe_usec:0
slowest_exe_time:1970-01-01 08:00:00.000000
slowest_exe_usec:0
slow_count:0
hit_count:0
mem_used:8192
1 rowin set (0.01 sec)
第二步 使用 plan_id 展示对应执行计划
获得 plan_id 后,用户可以使用 tenant_id 和 plan_id 访问 v$plan_cache_plan_explain 来展示该执行计划。
注意:
这里展示的计划为物理执行计划,在算子命名上会与 explain 所展示的逻辑执行计划有所不同。
OceanBase (root@oceanbase)> select *
from v$plan_cache_plan_explain
where tenant_id = 1001 and plan_id = 7;
+-----------+---------------+-------+---------+--------------------+------+------+------+
| TENANT_ID | IP | PORT | PLAN_ID | OPERATOR | NAME | ROWS | COST |
+-----------+---------------+-------+---------+--------------------+------+------+------+
| 1001 | 100.81.152.44 | 15212 | 7 | PHY_ROOT_TRANSMIT | NULL | 0 | 0 |
| 1001 | 100.81.152.44 | 15212 | 7 | PHY_INSERT | NULL | 0 | 0 |
| 1001 | 100.81.152.44 | 15212 | 7 | PHY_EXPR_VALUES | NULL | 0 | 0 |
+-----------+---------------+-------+---------+--------------------+------+------+------+
3 rows in set (0.01 sec)
注意:
- 如果访问 (g)v$plan_cache_plan_explain,必须给定 ip,port,tenant_id 和 plan_id 这四列的值.
- 如果访问 v$plan_cache_plan_explain,必须给定 tenant_id 和 plan_id 的值,否则,系统将返回空集。