首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何从PLSQL中获取执行计划

如何从PLSQL中获取执行计划
EN

Stack Overflow用户
提问于 2022-02-08 08:08:26
回答 2查看 57关注 0票数 0

我有一个代码片段,如:

代码语言:javascript
复制
declare
    cursor c is select ....
begin
    for i in c loop
        update table t1 where ti.c1 = i.column ...
    end loop;
end;

我想知道如何从update语句中获得执行计划,因为在表的列和游标的列之间有一个条件。

谁能给我个提示吗?

谢谢。

EN

回答 2

Stack Overflow用户

发布于 2022-02-08 19:39:06

最简单的方法可能是在计划执行时捕获它,方法是从v$session中注意到sql_idsql_child_number,然后运行

代码语言:javascript
复制
select plan_table_output
from   table(dbms_xplan.display_cursor(sql_id, sql_child_number));

或者,您可以将调用嵌入PL/SQL中以进行测试,并让它使用dbms_output.put_line输出计划。(每个循环迭代的计划都是相同的,除非您希望检查实际的行计数等,所以我添加了一个exit;语句,使它在一次执行后停止。)

代码语言:javascript
复制
declare
    cursor c is select * from departments;
begin
    for r in c loop
        update employees e set e.email = e.email
        where  e.department_id = r.department_id;
        
        for p in (
            select p.plan_table_output
            from   table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST')) p
        )
        loop
            dbms_output.put_line(p.plan_table_output);
        end loop;
        
        rollback;
        exit;
    end loop;
end;

在我的19 c演示人力资源模式中给出了:

代码语言:javascript
复制
SQL_ID  b5xbwbu4kd3r4, child number 1
-------------------------------------
UPDATE EMPLOYEES E SET E.EMAIL = E.EMAIL WHERE E.DEPARTMENT_ID = :B1
 
Plan hash value: 4075606039
 
-------------------------------------------------------------------------------------------------
| Id  | Operation         | Name              | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
-------------------------------------------------------------------------------------------------
|   0 | UPDATE STATEMENT  |                   |      1 |        |      0 |00:00:00.01 |       4 |
|   1 |  UPDATE           | EMPLOYEES         |      1 |        |      0 |00:00:00.01 |       4 |
|*  2 |   INDEX RANGE SCAN| EMP_DEPARTMENT_IX |      1 |      1 |      1 |00:00:00.01 |       1 |
-------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   2 - access("E"."DEPARTMENT_ID"=:B1)

要获得上面显示的实际行数,您需要

代码语言:javascript
复制
alter session set statistics_level = all;

或者在更新中包含/*+ gather_plan_statistics */提示。

票数 1
EN

Stack Overflow用户

发布于 2022-02-08 08:30:19

这只是一个普通的UPDATE语句。在循环中,它执行逐行(从游标返回)(不过,它可能一次更新多个行,具体取决于它的(UPDATE's) WHERE子句)。

因此,您只需从循环中“提取”并单独解释它,例如,如果是的话

代码语言:javascript
复制
cursor c is
  select id, job from emp_2;
begin
  for i in c loop
    update emp e set e.job = i.job where e.id = i.id;
  end loop;
end;

假设游标返回的行之一具有id = 7369job = CLERK,则

代码语言:javascript
复制
explain plan for update emp e set e.job = 'CLERK' where e.id = 7369;

select * from plan_table;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71030413

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档