小说oracle数据库,ORACLE小小说之武朝迷案

4、峰回路转

为什么会有那么多次的逻辑读和递归?看来看执行计划还是太表面了,难以回答ORACLE内部在做啥小动作,不查出问题所在,不将谜团大白于天下,誓不罢休!

试试10046trace吧,看看整个执行开始到结束,到底在执行什么,等待什么?玩啥猫腻!

分别做了两次10046TRACE,具体见附件《10046trace_notebook.txt》和《10046trace_service.txt》

仔细观察,终于有重大发现了,笔记本中环境10046trace_notebook.txt

SELECT PERSON

FROM

TACHE WHERE FLOW_ID = :B1 AND STATE <> 'F'

call     count       cpu    elapsed       disk      query    current        rows

------- ------  -------- ---------- ---------- ---------- ----------  ----------

Parse        1      0.00       0.00          0          0          0           0

Execute  65249      2.26       1.90          0          0          0           0

Fetch    65249      1.23       1.30          0      65243          0           0

------- ------  -------- ---------- ---------- ---------- ----------  ----------

total   130499      3.50       3.20          0      65243          0           0

这里怎么跑出一个这样的语句,Eeecute6万多次最终获取0行

而10046trace_service.txt中类似的地方确实如下,rows显示为65331和前者为0!有所发现。

SELECT PERSON

FROM

TACHE WHERE FLOW_ID = :B1 AND STATE <> 'F'

call     count       cpu    elapsed       disk      query    current        rows

------- ------  -------- ---------- ---------- ---------- ----------  ----------

Parse        1      0.00       0.00          0          0          0           0

Execute  65339      0.78       0.75          0          0          0           0

Fetch   130670    148.79     145.17          0   32714110          0       65331

------- ------  -------- ---------- ---------- ---------- ----------  ----------

total   196010    149.58     145.93          0   32714110          0       65331

继续分析发现 10046trace_service.txt还有如下调用,而10046trace_notebook.txt根本找不到如下两处调用!

SELECT PKP_FLOW_FUNCTION.GETSTAFFNAMEBYID(LTRIM(RTRIM(TO_CHAR(:B1 ))))

FROM

DUAL

call     count       cpu    elapsed       disk      query    current        rows

------- ------  -------- ---------- ---------- ---------- ----------  ----------

Parse        1      0.00       0.00          0          0          0           0

Execute 522102      7.43       6.78          0          0          0           0

Fetch   522102     42.59      42.17          0          0          0      522102

------- ------  -------- ---------- ---------- ---------- ----------  ----------

total   1044205     50.03      48.96          0          0          0      522102

SELECT NAME

FROM

STAFF_INFO WHERE STAFF_ID = :B1

call     count       cpu    elapsed       disk      query    current        rows

------- ------  -------- ---------- ---------- ---------- ----------  ----------

Parse        1      0.00       0.00          0          0          0           0

Execute 522102      8.51       7.78          0          0          0           0

Fetch   522102     21.35      20.21          0    4110939          0      456771

------- ------  -------- ---------- ---------- ---------- ----------  ----------

total   1044205     29.86      27.99          0    4110939          0      456771

仔细观察,还有新发现, 10046trace_service.txt还有如下递归调用 统计信息,而10046trace_notebook.txt

根本找不到!

RECURSIVE STATEMENTS

OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS

call     count       cpu    elapsed       disk      query    current        rows

------- ------  -------- ---------- ---------- ---------- ----------  ----------

Parse       11      0.00       0.01          0          0          0           0

Execute 1109552     16.74      15.33          0          0          0           0

Fetch   1174883    212.73     207.57          1   36825069          0     1044211

------- ------  -------- ---------- ---------- ---------- ----------  ----------

total   2284446    229.48     222.92          1   36825069          0     1044211

看来,这个递归毫无疑问来自函数的调用,仔细回到复杂的SQL脚本一看,发现了原先SQL中有函数

Pkp_Flow_Function.Getflowcurstaffname(a.Flow_Id) Flow_Operator,

查看这个函数调用的代码写法

FUNCTION getFlowCurStaffName(in_flow_id in number) RETURN VARCHAR2 IS

ss         VARCHAR2(255);

person1    VARCHAR2(255);

v_tabArray PKP_STRING_UTIL.varArray;

CURSOR c2 IS

SELECT person

FROM tache

WHERE flow_id = in_flow_id

AND STATE <> 'F';

BEGIN

--从环节表中取得

FOR rel1 IN c2 LOOP

v_tabArray := PKP_STRING_UTIL.split(rel1.person, ',');

FOR i IN 1 .. v_tabArray.COUNT() LOOP

SELECT getStaffNameById(LTRIM(RTRIM(TO_CHAR(v_tabArray(i)))))

INTO person1

FROM dual;

ss := ss || person1 || ' ';

END LOOP;

END LOOP;

RETURN(ss);

END getFlowCurStaffName;

其中getFlowCurStaffName函数还调用了getStaffNameById函数,具体如下:

FUNCTION getStaffNameById(in_staff_id IN varchar2) return varchar2 is

ret varchar2(255);

begin

select NAME INTO ret FROM STAFF_INFO WHERE STAFF_ID = in_staff_id;

return(ret);

end getStaffNameById;

而这些语句都出现在刚才的 10046trace_service.txt中,看来问题就出在这个函数调用中了!

虽然函数中的语句为什么与部分没有出现在10046trace_notebook.txt中这个问题我还无法回答,但是我相信,真相已经离我们很近了!

[本帖最后由 wabjtam123 于 2010-3-16 13:01 编辑]

267abf8789d6bad6eaf3c8c87b18d9ed.gif

2010-3-16 13:01 上传

点击文件名下载附件

16.89 KB, 下载次数: 48

267abf8789d6bad6eaf3c8c87b18d9ed.gif

2010-3-16 13:01 上传

点击文件名下载附件

15.57 KB, 下载次数: 49

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值