我同意已经给出的建议,开始弄清楚你的代码在哪里花费时间。但是,您的情况很常见,我想我认识到这种情况:您已经对更新语句进行了编码,以便为该类型的 GL_DISTRIBUTION 的每一行访问其他表。
解决方案是重写您的更新语句,我看到了两种有效地做到这一点的可能性:
1)更新一个选择语句(UPDATE(SELECT ...)SET ... WHERE ...)。这需要一些唯一的键约束或使用 BYPASS_UJVC 提示。
2) 使用 MERGE 语句。
下面是一个如何使用单个合并语句重写代码的示例。我期待性能大幅提升,因为现在对每个表使用单个外连接完成对其他表的访问,而不是对 GL_DISTRIBUTION 表中的每一行。
这个例子。测试数据:
SQL> create table gl_distribution (tr_number, tr_type, gl_date)
2 as
3 select '1', 'ADJST', date '2011-01-01' from dual union all
4 select '2', 'ADJST', null from dual union all
5 select '3', 'PRTAJ', date '2011-01-01' from dual union all
6 select '4', 'SYSPY', date '2011-01-01' from dual union all
7 select '5', 'RCRPAY', date '2011-01-01' from dual
8 /
Table created.
SQL> create table adjustments (adj_number, adj_date)
2 as
3 select 1, sysdate from dual union all
4 select 2, sysdate from dual
5 /
Table created.
SQL> create table party_adjustment (party_adj_number, party_adj_date)
2 as
3 select 3, sysdate from dual union all
4 select 33, sysdate from dual
5 /
Table created.
SQL> create table payments_to_vendors (ven_pay_vou_number, ven_pay_vou_date)
2 as
3 select 34, sysdate from dual
4 /
Table created.
SQL> create table sys_payments_header (ref_number,cheque_date)
2 as
3 select 4, sysdate from dual
4 /
Table created.
SQL> create table purchase_invoice_header (piv_number,posted_date)
2 as
3 select 35, sysdate from dual
4 /
Table created.
SQL> create table reverse_history (tr_number,doc_date,tr_type)
2 as
3 select 5, sysdate, 'CRPAY' from dual
4 /
Table created.
SQL>
您的程序(用于比较):
SQL> CREATE OR REPLACE PROCEDURE UPDATE_CRDT_JV
2 IS
3 BEGIN
4 UPDATE GL_DISTRIBUTION
5 SET GL_DATE = (SELECT ADJ_DATE FROM ADJUSTMENTS WHERE ADJ_NUMBER = TO_NUMBER(TR_NUMBER))
6 WHERE TR_TYPE = 'ADJST'
7 ;
8 UPDATE GL_DISTRIBUTION
9 SET GL_DATE = (SELECT PARTY_ADJ_DATE FROM PARTY_ADJUSTMENT
10 WHERE PARTY_ADJ_NUMBER = TO_NUMBER(TR_NUMBER))
11 WHERE TR_TYPE = 'PRTAJ'
12 ;
13 UPDATE GL_DISTRIBUTION
14 SET GL_DATE = (SELECT VEN_PAY_VOU_DATE FROM PAYMENTS_TO_VENDORS
15 WHERE VEN_PAY_VOU_NUMBER = TO_NUMBER(TR_NUMBER))
16 WHERE TR_TYPE = 'CRPAY'
17 ;
18 UPDATE GL_DISTRIBUTION
19 SET GL_DATE = (SELECT CHEQUE_DATE FROM SYS_PAYMENTS_HEADER WHERE
20 REF_NUMBER = TO_NUMBER(TR_NUMBER))
21 WHERE TR_TYPE = 'SYSPY'
22 ;
23 UPDATE GL_DISTRIBUTION
24 SET GL_DATE = (SELECT POSTED_DATE FROM PURCHASE_INVOICE_HEADER WHERE
25 POSTED_DATE IS NOT NULL AND PIV_NUMBER = TO_NUMBER(TR_NUMBER))
26 WHERE TR_TYPE = 'CRINV'
27 ;
28 UPDATE GL_dISTRIBUTION
29 SET GL_dATE = (SELECT DOC_dATE FROM REVERSE_HISTORY
30 WHERE TR_NUMBER = TO_NUMBER(GL_DISTRIBUTION.TR_NUMBER)
31 AND DOC_dATE IS NOT NULL AND TR_TYPE IN ('SYSPY','CRPAY'))
32 WHERE TR_TYPE IN ('RSYSPY','RCRPAY')
33 ;
34 --commit;
35 --UPDATE_INV_DET;
36 END;
37 /
Procedure created.
SQL>
我的建议:
SQL> create procedure new_update_crdt_jv
2 as
3 begin
4 merge into gl_distribution d
5 using ( select to_number(d.tr_number) tr_number
6 , coalesce
7 ( a.adj_date
8 , pa.party_adj_date
9 , pv.ven_pay_vou_date
10 , sph.cheque_date
11 , pih.posted_date
12 , rh.doc_date
13 ) new_date
14 from gl_distribution d
15 left outer join adjustments a
16 on to_number(d.tr_number) = a.adj_number
17 and d.tr_type = 'ADJST'
18 left outer join party_adjustment pa
19 on to_number(d.tr_number) = pa.party_adj_number
20 and d.tr_type = 'PRTAJ'
21 left outer join payments_to_vendors pv
22 on to_number(d.tr_number) = pv.ven_pay_vou_number
23 and d.tr_type = 'CRPAY'
24 left outer join sys_payments_header sph
25 on to_number(d.tr_number) = sph.ref_number
26 and d.tr_type = 'SYSPY'
27 left outer join purchase_invoice_header pih
28 on to_number(d.tr_number) = pih.piv_number
29 and d.tr_type = 'CRINV'
30 left outer join reverse_history rh
31 on to_number(d.tr_number) = rh.tr_number
32 and rh.tr_type in ('SYSPY','CRPAY')
33 and d.tr_type in ('RSYSPY','RCRPAY')
34 ) n
35 on ( d.tr_number = n.tr_number)
36 when matched then
37 update set d.gl_date = n.new_date
38 ;
39 end new_update_crdt_jv;
40 /
Procedure created.
SQL>
让我们运行您的程序:
SQL> select * from gl_distribution
2 /
T TR_TYP GL_DATE
- ------ -------------------
1 ADJST 01-01-2011 00:00:00
2 ADJST
3 PRTAJ 01-01-2011 00:00:00
4 SYSPY 01-01-2011 00:00:00
5 RCRPAY 01-01-2011 00:00:00
5 rows selected.
SQL> exec update_crdt_jv
PL/SQL procedure successfully completed.
SQL> select * from gl_distribution
2 /
T TR_TYP GL_DATE
- ------ -------------------
1 ADJST 31-03-2011 14:41:19
2 ADJST 31-03-2011 14:41:19
3 PRTAJ 31-03-2011 14:41:19
4 SYSPY 31-03-2011 14:41:19
5 RCRPAY 31-03-2011 14:41:19
5 rows selected.
SQL> rollback
2 /
Rollback complete.
SQL>
我的过程返回相同的结果:
SQL> exec new_update_crdt_jv
PL/SQL procedure successfully completed.
SQL> select * from gl_distribution
2 /
T TR_TYP GL_DATE
- ------ -------------------
1 ADJST 31-03-2011 14:41:19
2 ADJST 31-03-2011 14:41:19
3 PRTAJ 31-03-2011 14:41:19
4 SYSPY 31-03-2011 14:41:19
5 RCRPAY 31-03-2011 14:41:19
5 rows selected.
希望这可以帮助。
问候,
罗布。