Oracle11新特性——PLSQL新特性(二)

打算写一系列的文章介绍11g的新特性和变化。

11gPL/SQL新增了很多特性,在性能和易用性方面做了不少的提升,还有一些功能性的增强。

这篇介绍一下PLSQLSEQUENCE的改进。

Oracle11新特性——PLSQL新特性(一):http://yangtingkun.itpub.net/post/468/395965


以前取SEQUENCENEXTVALCURRVAL只能通过SQL语句,现在可以在PL/SQL中通过赋值语句获取:

SQL> CREATE SEQUENCE S_ID;

序列已创建。

SQL> SET SERVEROUT ON
SQL> DECLARE
2 V_ID NUMBER;
3 BEGIN
4 V_ID := S_ID.NEXTVAL;
5 DBMS_OUTPUT.PUT_LINE(V_ID);
6 END;
7 /
1

PL/SQL 过程已成功完成。

这种方法比使用SELECT INTO要方便,更重要的是,由于不执行SQL语句,这种方式的效率更高。

SQL> CREATE SEQUENCE S_1;

序列已创建。

SQL> CREATE SEQUENCE S_2;

序列已创建。

SQL> CREATE OR REPLACE PROCEDURE P1 AS
2 V_SEQ NUMBER;
3 BEGIN
4 FOR I IN 1..100000 LOOP
5 SELECT S_1.NEXTVAL INTO V_SEQ FROM DUAL;
6 END LOOP;
7 END;
8 /

过程已创建。

SQL> CREATE OR REPLACE PROCEDURE P2 AS
2 V_SEQ NUMBER;
3 BEGIN
4 FOR I IN 1..100000 LOOP
5 V_SEQ := S_2.NEXTVAL;
6 END LOOP;
7 END;
8 /

过程已创建。

SQL> SET TIMING ON
SQL> EXEC P1

PL/SQL 过程已成功完成。

已用时间: 00: 00: 06.81
SQL> EXEC P2

PL/SQL 过程已成功完成。

已用时间: 00: 00: 06.35
SQL> EXEC P1

PL/SQL 过程已成功完成。

SQL的运行时间上看,二者的差别不大,使用赋值的方法似乎略快一些。不过采用赋值的方法最大的好处是可以减少LATCH,在多用户并发访问的情况下效率更高。

下面通过查询V$SESSTAT视图和V$LATCH视图,分布记录两个存储过程的执行统计信息,并将二者的差异显示出来。

在执行之前,需要先建立一张临时表:

SQL> SET TIMING OFF
SQL> CREATE GLOBAL TEMPORARY TABLE T_SESSION_STAT
2 (ID NUMBER, NAME VARCHAR2(100), VALUE NUMBER);

表已创建。

SQL> SET SERVEROUT ON
SQL> DECLARE
2 V_NUMBER1 NUMBER;
3 V_NUMBER2 NUMBER;
4 BEGIN
5
6 INSERT INTO T_SESSION_STAT SELECT 1, 'STAT:' || NAME, VALUE
7 FROM V$SESSTAT A, V$STATNAME B
8 WHERE A.STATISTIC# = B.STATISTIC#
9 AND A.SID = (SELECT SID FROM V$MYSTAT WHERE ROWNUM = 1)
10 UNION ALL
11 SELECT 1, 'LATCH:' || NAME, GETS VALUE FROM V$LATCH;
12
13 V_NUMBER1 := DBMS_UTILITY.GET_TIME;
14 P1;
15 V_NUMBER1 := DBMS_UTILITY.GET_TIME - V_NUMBER1;
16
17 INSERT INTO T_SESSION_STAT SELECT 2, 'STAT:' || NAME, VALUE
18 FROM V$SESSTAT A, V$STATNAME B
19 WHERE A.STATISTIC# = B.STATISTIC#
20 AND A.SID = (SELECT SID FROM V$MYSTAT WHERE ROWNUM = 1)
21 UNION ALL
22 SELECT 2, 'LATCH:' || NAME, GETS VALUE FROM V$LATCH;
23
24 V_NUMBER2 := DBMS_UTILITY.GET_TIME;
25 P2;
26 V_NUMBER2 := DBMS_UTILITY.GET_TIME - V_NUMBER2;
27
28 INSERT INTO T_SESSION_STAT SELECT 3, 'STAT:' || NAME, VALUE
29 FROM V$SESSTAT A, V$STATNAME B
30 WHERE A.STATISTIC# = B.STATISTIC#
31 AND A.SID = (SELECT SID FROM V$MYSTAT WHERE ROWNUM = 1)
32 UNION ALL
33 SELECT 3, 'LATCH:' || NAME, GETS VALUE FROM V$LATCH;
34
35 DBMS_OUTPUT.PUT_LINE('P1 EXECUTE ' || V_NUMBER1/100 || ' SECONDS');
36 DBMS_OUTPUT.PUT_LINE('P2 EXECUTE ' || V_NUMBER2/100 || ' SECONDS');
37
38 FOR C IN
39 (
40 SELECT *
41 FROM
42 (
43 SELECT A.NAME, C.VALUE + A.VALUE - 2 * B.VALUE VALUE
44 FROM
45 T_SESSION_STAT A,
46 T_SESSION_STAT B,
47 T_SESSION_STAT C
48 WHERE A.NAME = B.NAME
49 AND A.NAME = C.NAME
50 AND A.ID = 1
51 AND B.ID = 2
52 AND C.ID = 3
53 )
54 WHERE ABS(VALUE) > 100
55 ) LOOP
56 DBMS_OUTPUT.PUT_LINE(RPAD(C.NAME, 50, ' ') || C.VALUE);
57 END LOOP;
58
59 END;
60 /
P1 EXECUTE 6.29 SECONDS
P2 EXECUTE 6.34 SECONDS
STAT:session pga memory 131072
STAT:redo size -308
STAT:undo change vector size 292
LATCH:cache buffers chains -171
LATCH:redo allocation -103
LATCH:shared pool simulator -99993

PL/SQL 过程已成功完成。

二者的执行时间仍然相差不多,上面的差异中redoundo都不是关注的内容,采用SELECT INTO的方式会导致共享池的争用,而采用赋值的方式会占用更多的PGA内存。

LATCH是串行操作,一遍情况下内存不是问题,因此应该尽量选择来提高并发性能。不过根据测试也可以看到,二者的性能差异很小,选择哪种方法都不会带来明显的性能变化。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/4227/viewspace-69428/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/4227/viewspace-69428/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值