DBMS_PROFILER不能直接测单次执行耗时;它采样式统计语句级执行次数和相对耗时(时间片),需手动计算加权平均或结合DBMS_HPROF补充,精确毫秒级单次耗时应使用V$SQL或DBMS_MONITOR配合SQL ID追踪。
DBMS_PROFILER 能不能直接测单次执行耗时
不能。它不记录单次调用的 wall-clock 时间,而是采样式统计语句级执行次数和相对耗时(以“时间片”为单位),最终需要手动计算加权平均或结合 dbms_hprof 补充。想看精确毫秒级单次耗时,得用 v$sql 或 dbms_monitor 配合 sql id 追踪。
启用 DBMS_PROFILER 前必须确认的三件事
很多人跑完 profiler 发现数据为空,问题常出在前置条件没满足:
- 当前用户有
EXECUTE权限 onDBMS_PROFILER(不是只 grant public) - 目标存储过程所在 schema 已被显式授权:比如
GRANT EXECUTE ON your_proc TO profiler_user -
PLSQL_DEBUG = TRUE必须在编译时生效——重编译存储过程:ALTER PROCEDURE your_proc COMPILE DEBUG,光改 session 参数没用
运行 profiler 后查不到数据?重点检查这四个表
数据分散在四张系统表里,漏查任意一张都会误判“没采集到”:
-
PLSQL_PROFILER_RUNS:确认 runid 是否生成、status 是否为RUNNING或FINISHED -
PLSQL_PROFILER_UNITS:核对unit_name和unit_type是否匹配你的存储过程名和类型(比如PROCEDURE) -
PLSQL_PROFILER_DATA:主数据表,runid+unit_number+line#三者联合定位代码行耗时 -
PLSQL_PROFILER_GRANULARITY:确认采样粒度是LINE还是BLOCK,影响PLSQL_PROFILER_DATA.line#的含义
典型错误:只查 PLSQL_PROFILER_DATA 却没关联 PLSQL_PROFILER_UNITS,导致 unit_number 对不上,查不到任何行。
DBMS_PROFILER 在 12c+ 上的兼容性陷阱
Oracle 12.1 起默认禁用 DBMS_PROFILER,且官方推荐迁移到 DBMS_HPROF(堆栈式分析)或 DBMS_SQLTUNE(SQL 级别)。但迁移不是简单替换:
-
DBMS_HPROF不支持 PL/SQL 行级计数,只输出调用栈和总耗时,无法定位哪一行循环慢 -
DBMS_PROFILER的STOP_PROFILER在 RAC 环境下可能只停本实例,其他节点仍在采样 - 如果数据库启用了
PLSQL_CODE_TYPE = NATIVE,profiler 可能完全失效——必须设为INTERPRETED并重编译
真正难的不是启动 profiler,而是把 runid、unit_number、line#、total_time 四个字段串起来还原出哪段逻辑拖慢了整体,中间少一环就白忙活。


















