115 lines
3.9 KiB
Markdown
115 lines
3.9 KiB
Markdown
实时执行计划展示
|
|
=============================
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
使用 EXPLAIN 命令,可以展示出当前优化器所生成的执行计划,但该 SQL 在计划缓存中实际对应的计划可能与 EXPLAIN 的结果并不相同,造成这种现象的原因有很多,诸如统计信息变化、用户 session 变量设置变化等等。为了确定该 SQL 在系统中实际使用的执行计划,有时还需要进一步分析计划缓存中的物理执行计划。
|
|
|
|
用户可以通过查询 `(g)v$plan_cache_plan_explain` 虚拟表来展示某条 SQL 在计划缓存中的执行计划。
|
|
|
|
对于 plan cache 中 plan 的基本信息解释如下例所示:
|
|
|
|
```javascript
|
|
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` 视图,并提供租户 ID 和需要查询的 SQL 字符串(可以使用模糊匹配),查询该条 SQL 在计划缓存中对应的 `plan_id`。
|
|
|
|
```javascript
|
|
obclient>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 所展示的逻辑执行计划有所不同。
|
|
|
|
```javascript
|
|
obclient> 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)
|
|
```
|
|
|
|
|
|
**注意**
|
|
|
|
|
|
|
|
* 如果访问 `gv$plan_cache_plan_explain`,必须给定 `ip`,`port`,`tenant_id` 和 `plan_id` 这四列的值;
|
|
|
|
|
|
|
|
* 如果访问 `v$plan_cache_plan_explain`,必须给定 `tenant_id` 和 `plan_id` 的值,否则,系统将返回空集。
|
|
|
|
|
|
|
|
|
|
|