使用 Explain 命令,可以展示出当前优化器所生成的执行计划,但该 SQL 在计划缓存中实际对应的计划可能与 Explain 的结果并不相同,造成这种现象的原因有很多,诸如统计信息变化、用户 session 变量设置变化等等。为了确定该 SQL 在系统中实际使用的执行计划,有时还需要进一步分析计划缓存中的物理执行计划。

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

对于 plan cache 中 plan 的基本信息解释如下例所示:

  1. view_definition='SELECT *
  2. FROM oceanbase.gv$plan_cache_plan_explain
  3. WHERE IP =HOST_IP() AND PORT = RPC_PORT()'

字段定义如下表:

字段名称类型描述
TENANT_IDbigint(20)租户id
IPvarchar(32)ip地址
PORTbigint(20)端口号
PLAN_IDbigint(20)plan的id
OPERATORvarchar(128)operator的名称
NAMEvarchar(128)表的名称
ROWSbigint(20)预估的结果行数
COSTbigint(20)预估的代价
PROPERTYvarchar(256)对应operator的信息

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

OceanBase 的计划缓存是每个 server 一个计划缓存。查询本 server 上的计划缓存,用户可以直接访问 v$plan_cache_plan_stat 视图,并提供租户 id 和需要查询的 SQL 字符串(可以使用模糊匹配),查询该条 SQL 在计划缓存中对应的 plan id。

  1. OceanBase(root@oceanbase)>select *
  2. from v$plan_cache_plan_stat
  3. where tenant_id= 1001
  4. and statement like 'insert into t1 values%'\G
  5. ***************************1. row ***************************
  6. tenant_id: 1001
  7. svr_ip:100.81.152.44
  8. svr_port:15212
  9. plan_id: 7
  10. sql_id:0
  11. type: 1
  12. statement: insert into t1 values(1)
  13. plan_hash:1
  14. last_active_time:2016-05-28 19:08:57.416670
  15. avg_exe_usec:0
  16. slowest_exe_time:1970-01-01 08:00:00.000000
  17. slowest_exe_usec:0
  18. slow_count:0
  19. hit_count:0
  20. mem_used:8192
  21. 1 rowin set (0.01 sec)

第二步 使用得到的 plan id展示对应执行计划

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

注意:

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

  1. OceanBase (root@oceanbase)> select *
  2. from v$plan_cache_plan_explain
  3. where tenant_id = 1001 and plan_id = 7;
  4. +-----------+---------------+-------+---------+--------------------+------+------+------+
  5. | TENANT_ID | IP | PORT | PLAN_ID | OPERATOR | NAME | ROWS | COST |
  6. +-----------+---------------+-------+---------+--------------------+------+------+------+
  7. | 1001 | 100.81.152.44 | 15212 | 7 | PHY_ROOT_TRANSMIT | NULL | 0 | 0 |
  8. | 1001 | 100.81.152.44 | 15212 | 7 | PHY_INSERT | NULL | 0 | 0 |
  9. | 1001 | 100.81.152.44 | 15212 | 7 | PHY_EXPR_VALUES | NULL | 0 | 0 |
  10. +-----------+---------------+-------+---------+--------------------+------+------+------+
  11. 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 的值,否则,系统将返回空集。