【OceanBase 诊断调优】—— 如何在 OceanBase 数据库 Oracle 模式中定位存储过程内的慢 SQL

OceanBase 数据库 Oracle 模式中由于存储过程内 SQL 较多,存储过程执行慢时,定位具体慢的 SQL 较困难,OceanBase 数据库 V4.2.2 及之后版本,可以通过本文档方法查询存储过程内 SQL 执行时间,可用于定位存储过程内的慢 SQL。

定位 OceanBase 数据库 Oracle 模式中定位存储过程内的慢 SQL

测试示例。

  1. 创建测试表 test。

    复制代码
    obclient [SYS]> CREATE TABLE test(n1 INT, d1 DATE);
    Query OK, 0 rows affected (0.183 sec)
  2. 创建存储过程。

    复制代码
    obclient [SYS]> create or replace PACKAGE pkg_test_plsql IS
        PROCEDURE test
         (
           pn_OperatorID IN INT
         );
       END pkg_test_plsql;
       /
    Query OK, 0 rows affected (0.072 sec)
    
    obclient [SYS]> create or replace PACKAGE BODY pkg_test_plsql IS
        PROCEDURE test
         (
           pn_OperatorID IN INT
         ) IS
         ln_OperatorID INT;
         BEGIN
           ln_OperatorID := pn_OperatorID;
           dbms_lock.sleep(3);
           INSERT INTO test(n1) VALUES(1);
           INSERT INTO test(n1) VALUES(2);
           COMMIT;
           SELECT count(1) INTO ln_OperatorID FROM test;
         END test;
       END pkg_test_plsql;
       /
     Query OK, 0 rows affected (0.131 sec)
  3. 在会话级别设置 nls_date_format 对应的日期格式。

    复制代码
    bclient [SYS]> ALTER SESSION SET nls_date_format='YYYY-MM-DD HH24:MI:SS';
    Query OK, 0 rows affected (0.001 sec)
  4. 获取系统时间。

    复制代码
    obclient [SYS]> SELECT sysdate from dual;

    输出结果如下:

    复制代码
    +---------------------+
    | SYSDATE             |
    +---------------------+
    | 2024-10-10 10:09:21 |
    +---------------------+
    1 row in set (0.001 sec)
  5. 调用存储过程。

    复制代码
    obclient [SYS]> call pkg_test_plsql.test(1);
    Query OK, 0 rows affected (3.199 sec)
  6. 查看 TRACE_ID。

    复制代码
    obclient [SYS]> SELECT last_trace_id() FROM dual;

    输出结果如下:

    复制代码
    +-----------------------------------+
    | LAST_TRACE_ID()                   |
    +-----------------------------------+
    | YB42AC1E87E1-000623EE413F689E-0-0 |
    +-----------------------------------+
    1 row in set (0.002 sec)
  7. 根据 TRACE_ID 查询存储过程内 SQL 执行时间。

    复制代码
    obclient [SYS]> SELECT
         to_char(to_date('1970-01-01', 'yyyy-mm-dd') + (request_time / 1000000 / 86400) + to_number(substr(tz_offset(sessiontimezone), 1, 3)) / 24, 'YYYYMMDD HH24:MI:SS') request_time_s,
         t.trace_id,
         t.request_type,
         t.pl_trace_id,
         to_char(t.query_sql) query_sql,
         t.elapsed_time/1000000 elapsed_time_s FROM gv$ob_sql_audit t WHERE
         user_name = 'SYS'
         AND t.pl_trace_id = 'YB42AC1E87E1-000623EE413F689E-0-0'
         AND query_sql NOT LIKE '%explain%'
         AND query_sql NOT LIKE '%request_time%' ORDER BY request_time DESC;

    输出结果如下:

    复制代码
    +-------------------+-----------------------------------+--------------+-----------------------------------+-------------------------------------------------+----------------+
    | REQUEST_TIME_S    | TRACE_ID                          | REQUEST_TYPE | PL_TRACE_ID                       | QUERY_SQL                                       | ELAPSED_TIME_S |
    +-------------------+-----------------------------------+--------------+-----------------------------------+-------------------------------------------------+----------------+
    | 20241010 10:09:25 | YB42AC1E87E1-000623EE413F68A1-0-0 |           11 | YB42AC1E87E1-000623EE413F689E-0-0 | select count(1) AS "COUNT(1)" from "SYS"."TEST" |        .003413 |
    | 20241010 10:09:25 | YB42AC1E87E1-000623EE413F68A0-0-0 |           11 | YB42AC1E87E1-000623EE413F689E-0-0 | insert into "SYS"."TEST"("N1") values(2)        |        .000102 |
    | 20241010 10:09:25 | YB42AC1E87E1-000623EE413F689F-0-0 |           11 | YB42AC1E87E1-000623EE413F689E-0-0 | insert into "SYS"."TEST"("N1") values(1)        |        .011947 |
    | 20241010 10:09:22 | YB42AC1E87E1-000623EE413F689E-0-0 |            2 | YB42AC1E87E1-000623EE413F689E-0-0 | call pkg_test_plsql.test(1)                     |       3.198526 |
    +-------------------+-----------------------------------+--------------+-----------------------------------+-------------------------------------------------+----------------+
    4 rows in set (0.049 sec)

    上述输出结果中 REQUEST_TYPE = 11 代表 PL 内 SQL。

    注意

    正常 SQL 走 SQL 引擎才会被记录到,如上测试示例中 dbms_lock.sleep 不会记录。

相关推荐
泡干脆面就番茄25 分钟前
MySQL_子查询_分页查询与联合查询详解
数据库·mysql
devpotato2 小时前
缓存与数据库更新顺序不一致问题
java·数据库·redis
天若有情6732 小时前
Node+MySQL小型全栈笔记项目实战课程分享
数据库·笔记·mysql
wxwx_bscxy3222 小时前
基于springboot宠物领养系统的设计与实现
数据库·spring boot·后端·spring·宠物
九月要晚安3 小时前
达梦DW与AFC对比
数据库
实战派K8S&DB3 小时前
如何在内网配置 TiDB 数据库 Agent
数据库·人工智能·分布式·tidb
实战派K8S&DB3 小时前
《基于 Dify + FastAPI + PyTiDB 搭建大模型驱动的 TiDB 智能运维 Agent》
运维·数据库·分布式·云原生·tidb·fastapi
SelectDB3 小时前
Apache Doris 5.0 年度版本前瞻(一):构建统一的多模湖仓实时分析平台
大数据·数据库·数据分析
小白学大数据3 小时前
超简单:用 Python 让 Excel 飞起来:用 openpyxl 把重复报表整理交给脚本
开发语言·数据库·python·excel
西索斯coding3 小时前
doubao-seed-2.1-turbo 调用一直 401 怎么办?pro 版同样的 Key 却正常——5 分钟排查定位指南
java·服务器·数据库·ai