DBMS_UTILITY.GET_TIME是最轻量的单次耗时记录方式,返回自实例启动以来的厘秒整数,需除以100换算为秒;不支持跨会话、异常路径自动捕获,须在每段逻辑及EXCEPTION中独立采样并及时换算。
dbms_utility.get_time 是最轻量、最直接的单次执行耗时记录方式,但它返回的是“百分之一秒”单位的整数,不是时间戳,也不能跨会话或自动捕获异常路径耗时。
DBMS_UTILITY.GET_TIME 返回值单位容易误解
它返回的是自数据库实例启动以来的 1/100 秒(即厘秒),不是毫秒,也不是 SYSDATE 差值。常见错误是直接相减后当“秒”用,忘了除以 100:
-
DBMS_UTILITY.GET_TIME返回值类型是BINARY_INTEGER,比如 12345678 —— 这代表 123456.78 秒,不是 12345678 毫秒 - 两值相减后必须除以
100才是真实秒数:(end_time - start_time) / 100 - 如果只关心相对大小(比如比较 A 步骤比 B 步骤慢多少),可以跳过除法,但输出日志时务必换算,否则
DBMS_OUTPUT.PUT_LINE里写“耗时 5000 秒”就成事故了
嵌套调用或异常路径下耗时会丢失
这个函数本身不感知 PL/SQL 控制流,一旦中间发生 EXCEPTION 跳出,end_time 就不会被赋值,后续计算会报 ORA-06502 或用到未初始化变量。正确做法是:
- 每个逻辑段都用独立的
start_time/end_time变量,避免复用同一组变量 - 在
EXCEPTION块里也补一次end_time := DBMS_UTILITY.GET_TIME,再计算该段实际耗时(哪怕只执行了半步) - 不要依赖
END处统一收口计时 —— 那里根本执行不到
和 SYSDATE 相比,精度高但无时区/日期信息
SYSDATE 做差能得小数天,再乘 24*60*60 换算成秒,看似方便,但有明显缺陷:
-
SYSDATE最小精度通常是 0.01 秒(取决于 OS 和 Oracle 版本),而DBMS_UTILITY.GET_TIME稳定提供厘秒级,对亚秒级操作更敏感 -
SYSDATE包含日期部分,做差可能因跨天导致负值(比如23:59:59.99 → 00:00:00.01),需额外处理;GET_TIME是单调递增整数,完全规避此问题 - 但
GET_TIME不带日期,无法知道“这一步发生在几点”,如需审计时间点,必须搭配SYSTIMESTAMP或SYSDATE单独记录
真正难的不是调用 DBMS_UTILITY.GET_TIME,而是确保每条异常分支都有对应的结束采样,且所有 /100 换算都落在 DBMS_OUTPUT 或日志表写入之前 —— 少一处,监控数据就断一节。


















