【发布时间】:2015-07-24 10:06:40
【问题描述】:
在 Oracle11g 中是否可以分析在 SELECT ... INTO ... 语句中在 plsql 代码中调用的存储函数?
对于分析,我使用DBMS_HPROF 实用程序。在DBMSHP_FUNCTION_INFO 表中运行分析后,我可以看到除了在SELECT ... INTO ... 中调用的函数之外的所有内容。
【问题讨论】:
标签: oracle plsql oracle11g profiling
在 Oracle11g 中是否可以分析在 SELECT ... INTO ... 语句中在 plsql 代码中调用的存储函数?
对于分析,我使用DBMS_HPROF 实用程序。在DBMSHP_FUNCTION_INFO 表中运行分析后,我可以看到除了在SELECT ... INTO ... 中调用的函数之外的所有内容。
【问题讨论】:
标签: oracle plsql oracle11g profiling
在 11g2 中,我的 HPROF 结果包括被称为
的包函数中的行SELECT my_pkg.my_func(x) INTO y FROM dual;
现在,我看不到每一行——通常只有 SQL 语句。例如,我在以下包中分析了“main_test”。
ALTER SESSION SET PLSQL_OPTIMIZE_LEVEL=0;
CREATE OR REPLACE PACKAGE matt_t1 AS
FUNCTION p (a NUMBER)
RETURN NUMBER;
PROCEDURE main_test;
END matt_t1;
CREATE OR REPLACE TYPE my_num_tab_type IS TABLE OF NUMBER;
CREATE OR REPLACE PACKAGE BODY matt_t1 AS
FUNCTION p (a NUMBER)
RETURN NUMBER IS
x NUMBER := 0;
t my_num_tab_type;
BEGIN
t := new my_num_tab_type();
for i in 1..10000 loop
x := ln (x+i);
t.extend();
t(i) := x;
END loop;
SELECT SUM(column_value) INTO x FROM TABLE(t);
RETURN x;
END p;
PROCEDURE main_test IS
x NUMBER;
BEGIN
FOR i IN 1 .. 100 LOOP
x := matt_t1.p (i);
DBMS_OUTPUT.put_line (x);
END LOOP;
END main_test;
END matt_t1;
在 HPROF 结果中,我看到了
的条目SELECT SUM(column_value) INTO x FROM TABLE(t);
但不是,例如,
x := ln (x+i);
无论我将函数 p 调用为 SELECT INTO 还是直接通过 PL/SQL 分配一个值,我都会得到相同的结果。无论哪种方式,10,000 个自然对数的所有时间都存储在行的 HPROF 条目下
FUNCTION p (a NUMBER)
如果我直接分析对 MATT_T1.P() 的调用,我也会得到相同的结果。
所以,我认为 HPROF 可能对它可以包含哪些类型的 PL/SQL 行有一些限制,但在我看来,调用方法 (SELECT..INTO) 与它无关。
【讨论】:
我在 DBMSHP_FUNCTION_INFO 中看到所有函数,例如 sql 函数,因为 dbms_hprof 不跟踪 sql 函数(如 ln、nvl... 等)。
create or replace function addNum(p1 number,p2 number) return
as
begin
return p1+p2;
end;
BEGIN
sys.DBMS_HPROF.START_PROFILING('TMP', 'test.trc');
END;
/
declare
n number;
n2 number;
n3 number;
BEGIN
select sum(1),max(1),ln(1) into n,n2,n3 from dual;
select max(addNum(1,level)) into n from dual connect by level<10;
END;
/
BEGIN
DBMS_HPROF.STOP_PROFILING;
END;
/
让我们进入trc文件。select sum(1) into n from dual;被标记为P#C SQL."".""."__static_sql_exec_line6" #6
,这意味着静态sql已经在第6行执行。select max(addNum(1,level)) into n from dual connect by level<10;这个选择以P#C SQL."".""."__static_sql_exec_line7" #7开始在第6行然后它自己切换到 plsql VM 以计算 addnum 的结果。 __plsql_vm 和 ADDNUM 在 trc 中出现了 9 次。
P#C SQL."".""."__static_sql_exec_line7" #7
P#X 3338
P#C PLSQL."".""."__plsql_vm" <--switch context
P#X 2
P#C PLSQL."ALUKASIEWICZ"."ADDNUM"::8."ADDNUM"#a7f835561d3611ed #1 <-- execut function
【讨论】:
您是否尝试在存储函数中启用分析器?这可能会创建单独的跟踪(不同的 runId )。
【讨论】: