可参考 MOS文档:
WAITEVENT: "PX Deq Credit: send blkd" (Doc ID 271767.1)
P1 = sleeptime/senderid
P2 = passes
P3 = qref
这是一个 IDLE wait event,需要查看 谁在等待(也就是那个 sender):
例如:
在某个 Slave 进程的 trace 文件中,出现如下信息:
WAIT #139280095023008: nam='PX Deq: reap credit' ela= 5 p1=0 p2=0 p3=0 obj#=-1 tim=1022377594644
WAIT #139280095023008: nam='PX Deq: reap credit' ela= 4 p1=0 p2=0 p3=0 obj#=-1 tim=1022377595160
WAIT #139280095023008: nam='PX Deq: Execution Msg' ela= 513 sleeptime/senderid=268632063 passes=1 p3=21463455416 obj#=-1 tim=1022455595161
通过 tkprof 整形后出现了这样的信息:
=====================================================================================
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
...
PX Deq: reap credit 271 0.00 0.00
PX Deq: Execution Msg 10 0.75 3.83
IPC send completion sync 2 0.00 0.00
PX Deq Credit: send blkd 102 32.63 94.44
PX Deq Credit: need buffer 8 0.47 1.78
...
=====================================================================================
表明等待 PX Deq Credit: send blkd 事件,共等待了 94.44 秒。
可以执行如下的脚本:
set SERVEROUTPUT on
undef p1
declare
inst varchar(20);
sender varchar(20);
begin
select bitand(&&p1, 16711680) - 65535 as SNDRINST,
decode(bitand(&&p1, 65535),65535, 'QC', 'P'||to_char(bitand(&&p1, 65535),'fm000') ) as SNDR
into inst , sender
from dual
where bitand(&&p1, 268435456) = 268435456;
dbms_output.put_line('Instance = '||inst);
dbms_output.put_line('Sender = '||sender );
end;
/
执行时会问 P1值,给出上面的sleeptime/senderid:268632063
经过计算后,得出答案:
Instance = 65537
Sender = QC
而且在任何一台运行Oracle 的机器上都如此。
这表明 :
作为 Coordinator 的 Process 在获取 Slave 进程的数据时,反应太慢了,
导致某些 Slave进行因为 Queue 满而不得不等待,进而拖慢了整个并行执行的速度。
这常常是由于 CPU 数目不足或者 系统中运行的 进程太多导致。可考虑 减小并行度。