熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Oracle >> 正文

小議Oracle11g的自治事務(六)

2013-11-13 16:09:45  來源: Oracle 

  自治事務提供了很方便的事務控制功能使得用戶可以在不影響當前事務的情況下提交或回滾對數據庫的修改那麼Oracle為了實現這個功能是否付出了很多的代價呢下面對比一下自治事務和普通事務的統計信息

   SQL> CREATE GLOBAL TEMPORARY TABLE T_SESSION_STAT
   (ID NUMBER NAME VARCHAR() VALUE NUMBER)
   ON COMMIT PRESERVE ROWS;

  表已創建 

   SQL> CREATE TABLE T_RECORD (ID NUMBER NAME VARCHAR());

  表已創建  

   SQL> CREATE OR REPLACE PROCEDURE P_TEST AS
   BEGIN
   INSERT INTO T_RECORD VALUES ( TEST);
   COMMIT;
   END;
   /

  過程已創建 

   SQL> CREATE OR REPLACE PROCEDURE P_TEST_AUTO AS
   PRAGMA AUTONOMOUS_TRANSACTION;
   BEGIN
   INSERT INTO T_RECORD VALUES ( TEST);
   COMMIT;
   END;
   /

  過程已創建 

   SQL> SET SERVEROUT OFF
  SQL> BEGIN
  
   INSERT INTO T_SESSION_STAT SELECT  NAME VALUE
   FROM V$SESSTAT A V$STATNAME B
   WHERE ASTATISTIC# = BSTATISTIC#
   AND ASID = (SELECT SID FROM V$MYSTAT WHERE ROWNUM = );
  
   P_TEST;
  
   INSERT INTO T_SESSION_STAT SELECT  NAME VALUE
   FROM V$SESSTAT A V$STATNAME B
   WHERE ASTATISTIC# = BSTATISTIC#
   AND ASID = (SELECT SID FROM V$MYSTAT WHERE ROWNUM = );
  
   P_TEST_AUTO;
  
   INSERT INTO T_SESSION_STAT SELECT  NAME VALUE
   FROM V$SESSTAT A V$STATNAME B
   WHERE ASTATISTIC# = BSTATISTIC#
   AND ASID = (SELECT SID FROM V$MYSTAT WHERE ROWNUM = );
  
   FOR C IN
   (
   SELECT *
   FROM
   (
   SELECT ANAME CVALUE + AVALUE   * BVALUE VALUE
   FROM
   T_SESSION_STAT A
   T_SESSION_STAT B
   T_SESSION_STAT C
   WHERE ANAME = BNAME
   AND ANAME = CNAME
   AND AID = 
   AND BID = 
   AND CID = 
   )
   WHERE ABS(VALUE) > 
   ) LOOP
   DBMS_OUTPUTPUT_LINE(RPAD(CNAME   ) || CVALUE);
   END LOOP;
  
   END;
   /
  PL/SQL 過程已成功完成
  SQL> TRUNCATE TABLE T_SESSION_STAT;

  表被截斷 

   SQL> SET SERVEROUT ON
  SQL> BEGIN
  
   INSERT INTO T_SESSION_STAT SELECT  NAME VALUE
   FROM V$SESSTAT A V$STATNAME B
   WHERE ASTATISTIC# = BSTATISTIC#
   AND ASID = (SELECT SID FROM V$MYSTAT WHERE ROWNUM = );
  
   P_TEST;
  
   INSERT INTO T_SESSION_STAT SELECT  NAME VALUE
   FROM V$SESSTAT A V$STATNAME B
   WHERE ASTATISTIC# = BSTATISTIC#
   AND ASID = (SELECT SID FROM V$MYSTAT WHERE ROWNUM = );
  
   P_TEST_AUTO;
  
   INSERT INTO T_SESSION_STAT SELECT  NAME VALUE
   FROM V$SESSTAT A V$STATNAME B
   WHERE ASTATISTIC# = BSTATISTIC#
   AND ASID = (SELECT SID FROM V$MYSTAT WHERE ROWNUM = );
  
   FOR C IN
   (
   SELECT *
   FROM
   (
   SELECT ANAME CVALUE + AVALUE   * BVALUE VALUE
   FROM
   T_SESSION_STAT A
   T_SESSION_STAT B
   T_SESSION_STAT C
   WHERE ANAME = BNAME
   AND ANAME = CNAME
   AND AID = 
   AND BID = 
   AND CID = 
   )
   WHERE ABS(VALUE) > 
   ) LOOP
   DBMS_OUTPUTPUT_LINE(RPAD(CNAME   ) || CVALUE);
   END LOOP;
  
   END;
   /

  recursive cpu usage

  session logical reads

  CPU used by this session

  enqueue releases

  db block gets

  db block gets from cache

  consistent gets

  consistent gets from cache

  consistent gets examination

  db block changes

  consistent changes

  commit cleanout failures: block lost

  commit cleanouts

  calls to kcmgcs

  calls to get snapshot scn: kcmgss

  redo size

  undo change vector size

  commit txn count during cleanout

  IMU commits

  IMU Flushes

  IMU undo allocation size

  PL/SQL 過程已成功完成

  由於第一次調用匿名塊和過程會產生會導致遞歸調用信息而這些可能干擾統計信息的結果因此執行兩次匿名塊取第二次的結果為最終結果

  從二者的差異可以看到自治事務產生的redo和undo都比普通事務要大一些這時可以理解的不過現在只是插入一條記錄不能說明什麼問題關鍵看這種差異隨事務的增大成比例增長還是基本維持原狀

  下面修改兩個存儲過程 

   SQL> CREATE OR REPLACE PROCEDURE P_TEST AS
   BEGIN
   FOR I IN  LOOP
   INSERT INTO T_RECORD VALUES ( TEST);
   END LOOP;
   COMMIT;
   END;
   /

  過程已創建 

   SQL> CREATE OR REPLACE PROCEDURE P_TEST_AUTO AS
   PRAGMA AUTONOMOUS_TRANSACTION;
   BEGIN
   FOR I IN  LOOP
   INSERT INTO T_RECORD VALUES ( TEST);
   END LOOP;
   COMMIT;
   END;
   /

  過程已創建

   SQL> EXEC P_TEST

  PL/SQL 過程已成功完成

   SQL> EXEC P_TEST_AUTO

  PL/SQL 過程已成功完成

   SQL> TRUNCATE TABLE T_SESSION_STAT;

  表被截斷

   SQL> DELETE T_RECORD;

  已刪除

   SQL> COMMIT;

  提交完成 

   SQL> BEGIN
  
   INSERT INTO T_SESSION_STAT SELECT  NAME VALUE
   FROM V$SESSTAT A V$STATNAME B
   WHERE ASTATISTIC# = BSTATISTIC#
   AND ASID = (SELECT SID FROM V$MYSTAT WHERE ROWNUM = );
  
   P_TEST;
  
   INSERT INTO T_SESSION_STAT SELECT  NAME VALUE
   FROM V$SESSTAT A V$STATNAME B
   WHERE ASTATISTIC# = BSTATISTIC#
   AND ASID = (SELECT SID FROM V$MYSTAT WHERE ROWNUM = );
  
   P_TEST_AUTO;
  
   INSERT INTO T_SESSION_STAT SELECT  NAME VALUE
   FROM V$SESSTAT A V$STATNAME B
   WHERE ASTATISTIC# = BSTATISTIC#
   AND ASID = (SELECT SID FROM V$MYSTAT WHERE ROWNUM = );
  
   FOR C IN
   (
   SELECT *
   FROM
   (
   SELECT ANAME CVALUE + AVALUE   * BVALUE VALUE
   FROM
   T_SESSION_STAT A
   T_SESSION_STAT B
   T_SESSION_STAT C
   WHERE ANAME = BNAME
   AND ANAME = CNAME
   AND AID = 
   AND BID = 
   AND CID = 
   )
   WHERE ABS(VALUE) > 
   ) LOOP
   DBMS_OUTPUTPUT_LINE(RPAD(CNAME   ) || CVALUE);
   END LOOP;
  
   END;
   /

  opened cursors cumulative

  recursive calls

  recursive cpu usage

  session logical reads

  CPU used by this session

  enqueue requests

  enqueue releases

  db block gets

  db block gets from cache

  consistent gets

  consistent gets from cache

  consistent gets examination

  db block changes

  consistent changes

  change write time

  free buffer requested

  commit cleanout failures: block lost

  commit cleanouts

  commit cleanouts successfully completed

  calls to kcmgcs

  calls to kcmgas

  calls to get snapshot scn: kcmgss

  redo entries

  redo size

  redo ordering marks

  undo change vector size

  no work consistent read gets

  deferred (CURRENT) block cleanout applications

  commit txn count during cleanout

  active txn count during cleanout

  cleanout number of ktugct calls

  IMU undo allocation size

  IMU Redo allocation size

  table scans (short tables)

  table scan rows gotten

  table scan blocks gotten

  cluster key scans

  cluster key scan block gets

  index fetch by key

  heap block compress

  session cursor cache hits

  buffer is not pinned count

  parse count (total)

  execute count

  PL/SQL 過程已成功完成

  IMU是g的IN MEMORY UNDO的縮寫這個值比較大主要是由於前面進行了DELETE後面又插入相同的數據因此Oracle采用了IMU操作拋去這個因素其他的差異於事務本身代價相比就小得多了

   SQL> TRUNCATE TABLE T_SESSION_STAT;

  表被截斷

  

   SQL> BEGIN
  
   INSERT INTO T_SESSION_STAT SELECT  NAME VALUE
   FROM V$SESSTAT A V$STATNAME B
   WHERE ASTATISTIC# = BSTATISTIC#
   AND ASID = (SELECT SID FROM V$MYSTAT WHERE ROWNUM = );
  
   P_TEST_AUTO;
  
   INSERT INTO T_SESSION_STAT SELECT  NAME VALUE
   FROM V$SESSTAT A V$STATNAME B
   WHERE ASTATISTIC# = BSTATISTIC#
   AND ASID = (SELECT SID FROM V$MYSTAT WHERE ROWNUM = );
  
   FOR C IN
   (
   SELECT *
   FROM
   (
   SELECT ANAME BVALUE  AVALUE VALUE
   FROM
   T_SESSION_STAT A
   T_SESSION_STAT B
   WHERE ANAME = BNAME
   AND AID = 
   AND BID = 
   )
   WHERE ABS(VALUE) > 
   ) LOOP
   DBMS_OUTPUTPUT_LINE(RPAD(CNAME   ) || CVALUE);
   END LOOP;
  
   END;
   /

  recursive calls

  session logical reads

  db block gets

  db block gets from cache

  db block changes

  redo entries

  redo size

  undo change vector size

  IMU undo allocation size

  IMU Redo allocation size

  execute count

  PL/SQL 過程已成功完成

  可見自治事務所帶來的額外的代價很小基本上可以不用過多的考慮


From:http://tw.wingwit.com/Article/program/Oracle/201311/17919.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.