这是我的问题,当我执行一个包来存档它在命令
上阻止的一些数据时FETCH cAPP_T_TMP BULK COLLECT
INTO t_app_t
limit nLIMIT;
但是当SQL Developper中的一个过程中的相同命令执行此操作时,需要运行16个secondes。
nLimit在包装中的误差为50 000。
简而言之,我在程序包中有一个其他程序可以使用相同的归档策略。唯一的区别是游标有不同的select语句。
这是我在pacakge中的代码:
procedure APP_TRX (p_date in varchar2, p_tableName out varchar2, p_timeRequired out varchar2, p_nbLinesTransfered out varchar2) is
cursor cAPP_T_TMP is
SELECT
APP.ID_APP,
APP.ID_T,
APP.ID_EVENT_CREA,
APP.DT_CREA,
APP.ID_EVENT_ANNUL,
APP.DT_ANNUL,
APP.ID_MAI,
APP.ID_F,
APP.M_APP,
APP.C_APP,
APP.T_C,
max(ATB.DT_EPUR) AS DT_EPUR
FROM APP_T APP
JOIN ARCH_T_BODY ATB ON APP.ID_TRX = ATB.ID_TRX_TRANSACTION
WHERE NOT EXISTS (SELECT TP.ID_TRX FROM T_PAP TP WHERE TP.ID_TRX = APP.ID_TRX)
AND NOT EXISTS (SELECT TI.ID_TRX FROM T_INST TI WHERE TI.ID_TRX = APP.ID_TRX)
AND NOT EXISTS (SELECT TP.ID_TRX FROM T_P TP WHERE TP.ID_TRX = APP.ID_TRX)
AND NOT EXISTS (SELECT TCD.ID_TRX FROM T_CRE TCD WHERE TCD.ID_TRX = APP.ID_TRX)
AND NOT EXISTS (SELECT MB.ID_TRX FROM M_BAN MB WHERE MB.ID_TRX = APP.ID_TRX)
GROUP BY APP.ID_APP,APP.ID_T,APP.ID_EVENT_CREA,APP.DT_CREA,APP.ID_EVENT_ANNUL,
APP.DT_ANNUL,APP.ID_MAI,APP.ID_F,APP.M_APP,APP.C_APP,APP.T_C;
type type_app_t is TABLE OF cAPP_T_TMP %ROWTYPE INDEX BY PLS_INTEGER;
t_app_t type_app_t ;
nLOT pls_integer := 1;
nbDeleted int :=0;
nbTransfered int :=0;
nbTransferedTemp int :=0; nbAlreadyIn int :=0;
begin
trc.trc_on('ARCHIVE_APP_T');
p_tableName := 'APP_T(B)';
allBEGIN_TIMESTAMP := systimestamp;
open cAPP_T_TMP ;
loop
lotBEGIN_TIMESTAMP := systimestamp;
dbms_application_info.set_module('before fetch',trim(to_char(nLOT * nLIMIT,'999G999G999')));
FETCH cAPP_T_TMP BULK COLLECT <-- here the command who block
INTO t_app_t
limit nLIMIT;
dbms_application_info.set_module('AFTER FETCH',trim(to_char(nLOT * nLIMIT,'999G999G999')));
exit when t_app_t.count = 0;
...
这是在Sql Developer中16个secondes中运行的代码:
declare
cursor cAPP_T_TMP is
SELECT
APP.ID_APP,
APP.ID_T,
APP.ID_EVENT_CREA,
APP.DT_CREA,
APP.ID_EVENT_ANNUL,
APP.DT_ANNUL,
APP.ID_MAI,
APP.ID_F,
APP.M_APP,
APP.C_APP,
APP.T_C,
max(ATB.DT_EPUR) AS DT_EPUR
FROM APP_T APP
JOIN ARCH_T_BODY ATB ON APP.ID_TRX = ATB.ID_TRX_TRANSACTION
WHERE NOT EXISTS (SELECT TP.ID_TRX FROM T_PAP TP WHERE TP.ID_TRX = APP.ID_TRX)
AND NOT EXISTS (SELECT TI.ID_TRX FROM T_INST TI WHERE TI.ID_TRX = APP.ID_TRX)
AND NOT EXISTS (SELECT TP.ID_TRX FROM T_P TP WHERE TP.ID_TRX = APP.ID_TRX)
AND NOT EXISTS (SELECT TCD.ID_TRX FROM T_CRE TCD WHERE TCD.ID_TRX = APP.ID_TRX)
AND NOT EXISTS (SELECT MB.ID_TRX FROM M_BAN MB WHERE MB.ID_TRX = APP.ID_TRX)
GROUP BY APP.ID_APP,APP.ID_T,APP.ID_EVENT_CREA,APP.DT_CREA,APP.ID_EVENT_ANNUL,
APP.DT_ANNUL,APP.ID_MAI,APP.ID_F,APP.M_APP,APP.C_APP,APP.T_C;
type type_app_t is TABLE OF cAPP_T_TMP %ROWTYPE INDEX BY PLS_INTEGER;
t_app_t type_app_t ;
compt int := 0;
nLIMIT pls_integer := 50000;
begin
DBMS_OUTPUT.put_line('before open ' || systimestamp);
open cAPP_T_TMP ;
loop
compt := compt +1;
DBMS_OUTPUT.put_line('before fetch ' || systimestamp);
FETCH cAPP_T_TMP BULK COLLECT
INTO t_app_t
limit nLIMIT;
DBMS_OUTPUT.put_line('after fetch ' || systimestamp);
exit when t_app_t.count = 0;
end loop;
close cAPP_T_TMP ;
DBMS_OUTPUT.put_line('after close ' || systimestamp || 'compt = ' || compt);
end;
正如你可以看到它的相同代码,但是由于我不知道它只是在包内部不起作用的原因。
我已经在包内部验证了我的其他程序,代码是相同的。
提前致谢。
编辑#1
我试图将程序提取到一个匿名块中,它就像一个魅力。所以我做了另一个测试,我试着直接调用我的包中的程序,但仍然遇到问题。最后,我尝试将我的anonyme块中的代码直接复制到包内,但同样的问题也出现了。为什么在我的包中,当数据在包外非常快时,我无法存档数据。
答案 0 :(得分:0)
似乎是由DBA针对OLTP优化的另一个用户执行了包。而且这个过程试图获取拥有数百万条记录的表格。因此,当我使用我的用户执行它时,它的工作方式会更好。