联系我们
18591797788
hubin@rlctech.com
北京市海淀区中关村南大街乙12号院天作国际B座1708室
18681942657
lvyuan@rlctech.com
上海市浦东新区商城路660号乐凯大厦26c-1
18049488781
xieyi@rlctech.com
广州市越秀区东风东路华宫大厦808号1608房
029-81109312
service@rlctech.com
西安市高新区天谷七路996号西安国家数字出版基地C座501
OceanBase 数据库中Oracle 租户PLSQL 调优的关键第一步,就是找到藏在程序包、存储过程里的慢 SQL。尤其是遇到嵌套调用的场景,手动排查堪比大海捞针。今天分享2个实战方法,帮你快速发现问题 SQL,为后续调优节省时间!
逐行追踪,锁定存过内慢 SQL 位置
DBMS_PROFILER 是 Oracle 自带的性能剖析工具,能记录 PLSQL 每一行代码的执行详情,并将结果汇总起来,详细展示 PL 执行过程中每一条语句的执行时间。直接定位慢 SQL 在存储过程中的具体行号。
例如当我们需要分析当前这个存过中哪里消耗的时间较多导致整个存过执行时间变慢。
DECLARE
v_1 VARCHAR2(100);
...
v_3 VARCHAR2(100);
BEGIN
CHS_TOA_TASK_PACKAGE.IS_HAS_MATCHED(?,?,v_1,v_2,v_3);
END;
可以通过如下步骤:
CALL dbms_profiler.start_profiler(run_comment => '任务名' || SYSDATE);
call DBMS_PROFILER.stop_profiler();
select * from PLSQL_PROFILER_RUNS WHERE run_comment='任务名';
select
a.runid,
a.unit_number,
a.unit_type,
a.unit_name,
b.line#,
b.total_occur,
b.total_ttime/1000000 as total_time_ms,
b.min_time as min_time_ns,
b.max_time as max_time_ns
from PLSQL_PROFILER_UNITS a,PLSQL_PROFILER_DATA b where a.runid=b.runid and a.unit_number=b.unit_number and a.runid=? order by total_time_ms desc fetch first 100 rows only;
如下图,unit_name表示调用的存过名称,line#表示在这个存过内的哪一行,total_occur(执行次数),total_time_ms(总耗时),可以通过这4个字段判断出存过执行到结束,那条sql执行耗时最大,从而定位。

会话级采集,快速筛选高消耗 SQL
操作步骤
select sys_context('userenv','sid') from dual;
select sql_id,to_char(substr(query_sql,1,80)),plan_id,round(avg(elapsed_time),2),sum(elapsed_time) sum ,count(*),PL_TRACE_ID from gv$ob_sql_audit where sid=? and user_name=? group by sql_id,plan_id, to_char(substr(query_sql,1,80)),PL_TRACE_ID order by sum;
参考结果如下,会详细列出所有sql的执行时间消耗,从而定位慢SQL,但缺点是无法知道sql在存过调用中的哪一位置。所以需要配合上面DBMS_PROFILER方式。

1.想精准定位慢 SQL 在存过中的行号:直接用 DBMS_PROFILER;
2.想快速筛选会话内高消耗 SQL:先用 gv$ob_sql_audit 做初步排查;
3.嵌套程序包场景:两者结合使用,效率翻倍,后续着重分析问题sql。
这两个方法覆盖了OceanBase 数据库Oracle 租户 PL 调优中慢 SQL 定位的核心场景,代码可直接复制套用。如果你也遇到 PLSQL 执行慢的问题,或是有独到的优化经验,欢迎在评论区留言分享,下次见!