在Oracle数据库开发中,PLSQL存储过程的性能直接影响业务系统的响应速度,很多开发人员遇到过程执行慢的问题时往往无从下手。下面我们就详细介绍PLSQL Procedure性能调优分析的完整方法。

一、先定位性能瓶颈点
调优的第一步是找到耗时最长的代码片段,避免盲目优化。Oracle提供了多个工具帮助我们定位问题:
1. 使用DBMS_PROFILER包
DBMS_PROFILER可以统计存储过程内每一行代码的执行次数和耗时,是最直接的性能分析工具。使用前需要先安装该包,执行以下语句:
-- 安装DBMS_PROFILER,需要用SYS用户执行 @?/rdbms/admin/profload.sql @?/rdbms/admin/proftab.sql
然后在存储过程执行前后启动和停止剖析:
DECLARE
l_result NUMBER;
BEGIN
-- 启动剖析
DBMS_PROFILER.START_PROFILER('test_procedure_profiler');
-- 执行要分析的存储过程
test_procedure(1, l_result);
-- 停止剖析
DBMS_PROFILER.STOP_PROFILER;
END;
/
-- 查询剖析结果,查看耗时最长的代码行
SELECT u.unit_name,
d.line#,
d.total_time,
d.total_occur
FROM plsql_profiler_units u
JOIN plsql_profiler_data d ON u.runid = d.runid AND u.unit_number = d.unit_number
WHERE u.unit_name = 'TEST_PROCEDURE'
ORDER BY d.total_time DESC;2. 查看AWR报告或ASH报告
如果存储过程是在生产环境运行,可以通过AWR或ASH报告查看该过程的整体耗时,以及等待事件类型,判断是CPU消耗过高还是存在IO等待等问题。
二、分析SQL语句的执行计划
存储过程中大部分性能问题都来自内部的SQL语句,需要针对每条SQL生成执行计划分析:
1. 使用EXPLAIN PLAN生成执行计划
可以对存储过程中的SQL单独提取出来,执行以下语句查看执行计划:
EXPLAIN PLAN FOR SELECT * FROM user_table WHERE id = 100; -- 查看执行计划 SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
2. 关键指标解读
执行计划中需要重点关注以下指标:
- COST:优化器估算的执行成本,数值越高资源消耗越大
- Cardinality:优化器估算的返回行数,和实际行数差异过大可能是统计信息过期
- Operation:执行的操作类型,全表扫描(TABLE ACCESS FULL)通常是优化重点
三、常见优化手段
1. SQL语句优化
尽量避免在存储过程中使用动态SQL,静态SQL的解析效率更高。对于频繁执行的查询,确保相关表的统计信息是最新的,执行以下语句收集统计信息:
BEGIN
DBMS_STATS.GATHER_TABLE_STATS(
ownname => 'SCOTT',
tabname => 'USER_TABLE',
cascade => TRUE
);
END;
/同时为查询条件的字段建立合适的索引,避免全表扫描,还要注意索引不要建在过多字段上,避免影响写入性能。
2. PLSQL代码逻辑优化
不要在循环里面执行单条SQL,尽量使用批量操作。比如批量插入可以使用FORALL,批量查询可以使用BULK COLLECT:
DECLARE
TYPE id_tab IS TABLE OF NUMBER;
TYPE name_tab IS TABLE OF VARCHAR2(50);
l_ids id_tab := id_tab(1,2,3,4,5);
l_names name_tab;
BEGIN
-- 批量查询
SELECT name BULK COLLECT INTO l_names
FROM user_table
WHERE id IN (SELECT COLUMN_VALUE FROM TABLE(l_ids));
-- 批量插入
FORALL i IN 1..l_names.COUNT
INSERT INTO user_table_log(name) VALUES(l_names(i));
END;
/3. 避免不必要的上下文切换
尽量减少PLSQL引擎和SQL引擎之间的切换次数,比如不要在循环里反复调用TO_CHAR、TO_DATE这类函数,可以在查询时统一处理,或者提前把转换结果存到变量中。
四、调优后验证
优化完成后,需要重新执行之前的性能分析步骤,对比优化前后的耗时和执行计划,确认优化效果。如果优化后性能提升不明显,需要重新检查是否遗漏了其他瓶颈点,比如是否存在锁等待、表碎片过多等问题,针对性处理即可。