技术开发 频道

用批量绑定大幅提高性能的一则案例

    3.3进一步改写存储过程(基于10g)

CREATE OR REPLACE PROCEDURE P_HANDLE_PIX_NEW_10( ai_rtd out number, as_rmsg out varchar2) IS TYPE t_pix_pointer IS TABLE OF PLS_INTEGER; TYPE t_pixid IS TABLE OF pix_trans.id%TYPE INDEX BY PLS_INTEGER; TYPE t_pixtype IS TABLE OF pix_trans.pixtype%TYPE INDEX BY PLS_INTEGER; TYPE t_actcode IS TABLE OF pix_trans.actcode%TYPE INDEX BY PLS_INTEGER; pix_id t_pixid; pix_pixtype t_pixtype; pix_actcode t_actcode; succ_pix_id t_pix_pointer := t_pix_pointer(); fail_pix_id t_pix_pointer := t_pix_pointer(); ll_begin number; ll_end number; BEGIN SELECT to_char(sysdate,'sssss') INTO ll_begin FROM dual; --获得pix信息 SELECT id,pixtype,actcode BULK COLLECT INTO pix_id,pix_pixtype,pix_actcode FROM pix_trans WHERE status = '00'; --如果集合为空,则退出 IF pix_id.count=0 THEN ai_rtd := 0; as_rmsg := 'No recoreds'; return; END IF; --逐条处理记录 FOR indx IN pix_id.first .. pix_id.last LOOP P_HANDLE_STOCK(pix_id(indx),pix_pixtype(indx),pix_actcode(indx),ai_rtd,as_rmsg); IF ai_rtd>0 THEN succ_pix_id.extend; succ_pix_id(succ_pix_id.last) := indx; ELSE fail_pix_id.extend; fail_pix_id(fail_pix_id.last) := indx; END IF; END LOOP; --将处理成功的记录插入历史表 FORALL indx IN VALUES OF succ_pix_id INSERT INTO pix_trans_his(id,pixtype,actcode) VALUES (pix_id(indx),pix_pixtype(indx),pix_actcode(indx)); --更新记录的成功标志 FORALL indx IN VALUES OF succ_pix_id UPDATE pix_trans SET status = '10' WHERE id = pix_id(indx); --更新记录的失败标志 FORALL indx IN VALUES OF fail_pix_id UPDATE pix_trans SET status = '10' WHERE id = pix_id(indx); SELECT to_char(sysdate,'sssss') INTO ll_end FROM dual; DBMS_OUTPUT.PUT_LINE('forall values of:' || to_char(ll_end - ll_begin)); END;

    在10g里,我们可以减少了两个集合,而只是引入一个失败的集合指针和一个成功的集合指针。通过失败的集合指针,我们可以找到失败的pix_trans.id,从而更新pix_trans表里对应的记录的状态;通过成功的集合指针,我们可以找到需要插入历史表的三个字段的值。

    那么这样改写以后的效果如何呢?我们来测试一下运行速度。

SQL> set serveroutput on; SQL> declare 2li_rtd number; 3ls_rmsg varchar2(255); 4begin 5p_handle_pix_new_10(li_rtd,ls_rmsg); 6end; 7/ forall values of:10 PL/SQL procedure successfully completed.

    可以看到,相比9i下的写法,速度提高了1秒钟。大约是9%左右。效果并不是很明显。

0
相关文章