【问题标题】:Oracle SQL Developer takes long time to connect, run, and disconnect from database when executing stored procedureOracle SQL Developer 在执行存储过程时需要很长时间来连接、运行和断开与数据库的连接
【发布时间】:2018-02-07 03:34:58
【问题描述】:

)

你们中的许多人已经熟悉如何使用此 UI 运行存储过程(选择一个包并在此处选择一个要运行的 sp)。因为我需要时间来运行一个存储过程,所以我在这里放了一些额外的信息。

DBMS_OUTPUT.ENABLE();
DBMS_OUTPUT.PUT_LINE(to_char(systimestamp, 'FF6');
-- Actual calling --
MY_SP(
   I_INPUT1 => I_INPUT1,
   O_OUTPUT1 => O_OUTPUT1
);
--------------------
DBMS_OUTPUT.PUT_LINE(to_char(systimestamp, 'FF6');

一旦我按下 OK 按钮,这些语句将显示(在日志窗口中):

同时在DBMS输出面板会显示开始时间和结束时间。

令我惊讶的是,我发现 DBMS 报告存储过程只需要几秒钟甚至几分之一秒即可运行,但“进程已退出”和“与数据库断开连接”语句不会 大约 16 秒(甚至更多)后才出现。 (仅供参考:我使用秒表来计算这 3 条语句出现在日志窗口中的时间。)

这是为什么呢?有人有任何想法吗?它与数据库服务器的负载有关吗?同时连接太多?我听说数据库在 AWS 中。有关系吗?

我已经在同一个包中测试了另一个存储过程,它不会受到同样的影响。

【问题讨论】:

  • 您是在调试还是在执行?如果执行,我不确定为什么您会看到连接和断开连接消息,因为在使用 SQL Developer 执行 pl/sql 时这些都不会发生
  • 即使我是 Oracle 新手,我也相信我正在执行。我打开一个包并右键单击以选择运行。我看到了那个 PL/SQL 对话框。我选择了一个存储过程。单击确定按钮后,Log 窗口(查看菜单 -> 日志)会显示并显示 3 条语句(连接到数据库、进程退出和与数据库断开连接)。 (问题已更新以显示日志窗口。)仅供参考:我使用 SQL Developer 版本 4.2.0.17.089。
  • 是的,你是对的,我的错。关闭连接可能需要很长时间的原因有多种 - 清理临时空间和各种其他事情
  • 杰夫,感谢您的回答。经过一番调查,我发现它是导致缓慢的选择之一。我有SELECT columnA, .., column D, (SELECT ActiveTime, DoneFlag, RANK() OVER (ORDER BY ActiveTime DESC) ... 我评论select... rank() over 并且(感知的)时间非常短。最终我只是重写了查询。

标签: oracle stored-procedures database-connection oracle-sqldeveloper


【解决方案1】:

当我发布这个问题时,我不打算回答自己,因为我完全不知道发生了什么。现在我知道发生了什么事。希望我的回答对其他人有所帮助。

问题

当我使用 UI 运行存储过程时,会出现日志窗口(查看 -> 日志)。首先它说“连接到数据库”。然后大约 16 秒后,出现第二条语句“进程退出”和第三条语句“与数据库断开连接”。 SQL Developer 似乎需要很长时间才能执行存储过程。我的下一步自然是调查存储过程中的 SQL 语句。

SQL

当我注释掉 SELECT...RANK OVER 时,所用时间从 16 秒减少到 1.2 秒。

SELECT a.columnA, a.columnB, 
....
, CASE WHEN (SELECT COUNT(*)
            FROM (SELECT ActiveTime, DoneFlag, ID
                  FROM (SELECT ActiveTime, DoneFlag, ID,
                        RANK() OVER (ORDER BY ActiveTime DESC) RM
                        FROM MAM) t
                  WHERE RM = 1
                  AND t.ID = a.WIN_ID AND t.DoneFlag = 'Y'
                 )
            ) > 0
 THEN 'Y' ELSE 'N' END AS RECEIVE_STATUS
 FROM ...

我重写了 SQL:

PROCEDURE myProcedure (
    ... )
AS
    V_ID     MAM.ID%type;
BEGIN
    SELECT ID
    INTO V_ID
    FROM (SELECT ActiveTime, DoneFlag, ID,
          RANK() OVER (ORDER BY ActiveTime DESC) RM
          FROM MAM) t
    WHERE RM = 1 AND t.DoneFlag = 'Y';

    OPEN P_RETURNCUR FOR
    SELECT a.columnA, a.columnB,
        ...
    , CASE WHEN V_ID = a.WIN_ID THEN 'Y' ELSE 'N' END AS RECEIVE_STATUS
    FROM ...

说明

SELECT... RANK OVERRM = 1 实际上从 MAM 表中拉出一行,而这一行不会改变关于 a.WIN_ID。所以我把那部分 SQL 提取出来。运行它并将值存储到 V_ID 中。我只需要将 V_ID 与每个 a.WIN_ID 进行比较。完成。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-25
    • 1970-01-01
    • 2021-09-19
    • 1970-01-01
    • 1970-01-01
    • 2017-02-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多