學習PLS_INTEGER,BINARY_INTEGER,INTEGER,NUMBER的概念及效能差異

wisdomone1發表於2012-09-14
學習PLS_INTEGER,BINARY_INTEGER,INTEGER,NUMBER的概念及區別;以及在效能方面的差異
         1,各個概念
              型別                是否可用於表列定義         概念                                      儲存情況
              ------------------------------------------------------
              PLS_INTEGER         不可,僅用於PLSQL塊        1,它儲存比NUMBER及子型別少                1,儲存有符號整形
                                                             2,它在計算採用硬體演算法,比NUMBER快,      2,取值範圍:-2147483648 到 2147483647
                                                                NUMBER採用庫演算法                        3,代表32BIT
                                                             3,如果精度在PLS_INTEGER之內,從速度上
                                                                最好用PLS_INTEGER,如果精度在其外
                                                                用INTEGER
                                                             4,如果多個PLS_INTEGER運算溢位,即使把運
                                                               算結果型別是NUMBER,也會報錯
                                                              
                                                              
              NUMBER              可以,也可用於PLSQL塊      1,儲存定點或浮點數                         1,取值在1E-130(不含)到1.0E126
                                                             2,如果運算結果在取值範圍,用它
                                                                如果運算超界,編譯報錯
                                                                如果NUMBER計算超界,結果未知
                                                                 可能產生不可信的結果和錯誤
                                                             3,定義:NUMBER(精度,小數位數)  
                                                             4,定義定點型NUMBER
                                                                  NUMBER(精度,小數位數)
                                                                定義浮點型NUMBER
                                                                  NUMBER,所謂浮點即小數位點不定
                                                                定義整型
                                                                  NUMBER(精度) 
                                                             5,精度取值範圍:38數字位數,如果未指定精度
                                                                預設取39或40或系統支援最大值,二者取小者
                                                             6,小位位數,取值是-84到127
                                                                小位位數與四捨五入有關,即3.542為3.54
                                                                負小數位數2比如:3452為3400
                                                                小數位數是0,比如3.456為3
                                                             7,如未指定小數位數,預設是0
                                  
           
             INTEGER           可用於表列,也可用於PLSQL塊   1,INTEGER是NUMBER子型別
                                                                      --說明INTEGER的子型別
                                                                 SQL> create table t_integer(a integer);
                                                                 表已建立。
                                                                
                                                                 SQL> desc t_integer;
                                                                  名稱                                      是否為空? 型別
                                                                  ----------------------------------------- -------- -----------
                                                                
                                                                  A                                                  NUMBER(38)    
             
             
             
              BINARY_INTEGER   不可用於表列,但可用於PLSQL塊      1,它和PLS_INTEGER是一樣的,它的子型別可視
                                                                     PLS_INTEGER的子型別
                                                                  3,BINARY_INTEGER子型別
                                                                       NATURAL
                                                                       NATURAIN 
                                                                       POSITIVE
                                                                       POSITIVEN
                                                                       SIGNTYPE
                                                                      
              BINARY_FLOAT或
              BIANRY_DOUBLE    不可用於表列,但可用於PLSQL塊      1,用於高速的科學計算
                                                                  2,單精度或雙精度的IEEE754單精度的浮點數
                                                                  3,此型別以F結尾,如:2.04F或3.004D
                                                                  4,與此型別相關的運算產生結果要進行檢查,而會
                                                                     不會引發異常
                                                                  5,為了處理OVERFLOW,UNDERFLOW及其它情況,可用
                                                                     幾個預定義的常量:
                                                                       BINARY_FLOAT_NAN,
                                                                       BINARY_FLOAT_INFINITY
                                                                       BINARY_FLOAT_MAX_NORMAL
                                                                       BINARY_FLOAT_MIN_NORMAL
                                                                       BINARY_FLOAT_MAX_SUBNORMAL
                                                                       BIANRY_FLOAT_MIN_SUBNORMAL                                                                 
        
         2,用PLSQL進行測試,小資料量,大資料量,大資料量測試,比對各個型別的區別
               1,定義上述型別的表
                   CREATE TABLE T_NUMBER(A NUMBER);
                   CREATE TABLE T_INTEGER(A INTEGER);
                   CREATE TABLE T_PLS_INTEGER(A NUMBER);
                   CREATE TABLE T_BINARY_INTEGER(A NUMBER);
                   CREATE TABLE T_BINARY_FLOAT(A NUMBER);                
               2,以小大大資料量進行對比測試   
                   1,1000條以下 小資料量
                   2,100000條  大資料量
                   3,100000000條  大資料量 
                  
                   4,分別以上述資料量對1定義的6個表進行INSERT
                     
                      --1,以小資料量測試NUMBER型別的INSERT
                      DECLARE
                        V_UPPER NUMBER;
                      BEGIN
                       V_UPPER:=1000;
                       FOR I IN 1..V_UPPER LOOP
                         INSERT INTO T_NUMBER VALUES(I);
                       END LOOP;
                      END;
                      已用時間:  00: 00: 00.09
                    
                     --2,以小資料量測試INTEGER型別的INSERT
                      DECLARE
                        V_UPPER INTEGER;
                      BEGIN
                       V_UPPER:=1000;
                       FOR I IN 1..V_UPPER LOOP
                         INSERT INTO T_INTEGER VALULES(I);
                       END LOOP;
                      END;  
                      已用時間:  00: 00: 00.05
                     
                     
                     
                      --3,以小資料量測試PLS_INTEGER型別的INSERT
                      DECLARE
                        V_UPPER PLS_INTEGER;
                      BEGIN
                       V_UPPER:=1000;
                       FOR I IN 1..V_UPPER LOOP
                         INSERT INTO T_PLS_INTEGER VALUES(I);
                       END LOOP;
                      END;  
                      已用時間:  00: 00: 00.06
                     
                     
                      --4,以小資料量測試BINARY_INTEGER型別的INSERT
                      DECLARE
                        V_UPPER BINARY_INTEGER;
                      BEGIN
                       V_UPPER:=1000;
                       FOR I IN 1..V_UPPER LOOP
                         INSERT INTO T_BINARY_INTEGER VALUES(I);
                       END LOOP;
                      END;
                      已用時間:  00: 00: 00.10
                     
                     
                     
                     
                      --5,以小資料量測試BINARY_FLOAT型別的INSERT
                      DECLARE
                        V_UPPER BINARY_FLOAT;
                      BEGIN
                       V_UPPER:=1000;
                       FOR I IN 1..V_UPPER LOOP
                         INSERT INTO T_BINARY_FLOAT VALUES(I);
                       END LOOP;
                      END;
                      已用時間:  00: 00: 00.13
                     
                      --6,小結:用小資料量INSERT,INTEGER最快,而BINARY_FLOAT最慢,BINARY_INTEGER僅比最慢的
                                BINARY_FLOAT快一點,倒數第二
                                PLS_INTEGER比INTEGER稍慢一點兒
                               
           ---------------------------------------------------
 
 
 --1,以中資料量測試NUMBER型別的INSERT
                      --先清空上述5個表
                      TRUNCATE TABLE T_NUMBER;
                      TRUNCATE TABLE T_INTEGER;
                      TRUNCATE TABLE T_PLS_INTEGER;
                      TRUNCATE TABLE T_BINARY_INTEGER;
                      TRUNCATE TABLE T_BINARY_FLOAT;
                     
                      --1,以中資料量測試NUMBER型別的INSERT
                      DECLARE
                        V_UPPER NUMBER;
                      BEGIN
                       V_UPPER:=100000;
                       FOR I IN 1..V_UPPER LOOP
                         INSERT INTO T_NUMBER VALUES(I);
                       END LOOP;
                      END;
                      已用時間:  00: 00: 03.57
                    
                     --2,以中資料量測試INTEGER型別的INSERT
                      DECLARE
                        V_UPPER INTEGER;
                      BEGIN
                       V_UPPER:=100000;
                       FOR I IN 1..V_UPPER LOOP
                         insert into  t_integer values(I);
                       END LOOP;
                      END;  
                      已用時間:  00: 00: 05.89
                     
                     
                     
                      --3,以中資料量測試PLS_INTEGER型別的INSERT
                      DECLARE
                        V_UPPER PLS_INTEGER;
                      BEGIN
                       V_UPPER:=100000;
                       FOR I IN 1..V_UPPER LOOP
                         INSERT INTO T_PLS_INTEGER VALUES(I);
                       END LOOP;
                      END;  
                      已用時間:  00: 00: 03.00
                     
                     
                      --4,以中資料量測試BINARY_INTEGER型別的INSERT
                      DECLARE
                        V_UPPER BINARY_INTEGER;
                      BEGIN
                       V_UPPER:=100000;
                       FOR I IN 1..V_UPPER LOOP
                         INSERT INTO T_BINARY_INTEGER VALUES(I);
                       END LOOP;
                      END;
                      已用時間:  00: 00: 03.08
                     
                     
                     
                     
                      --5,以中資料量測試BINARY_FLOAT型別的INSERT
                      DECLARE
                        V_UPPER BINARY_FLOAT;
                      BEGIN
                       V_UPPER:=100000;
                       FOR I IN 1..V_UPPER LOOP
                         INSERT INTO T_BINARY_FLOAT VALUES(I);
                       END LOOP;
                      END;
                      已用時間:  00: 00: 03.27
                     
                      --小結:PLS_INTEGER最快,INTEGER最慢
                              BINARY_INTEGER稍決於PLS_INTEGER
-------------------------------------
-------------------------------------
繼續昨天的基於不同資料型別PLS_INTEGER,NUMBER,INTEGER,BINARY_INTEGER,BINARY_FLOAT的效能測試
       1,修正如下PLSQL塊,因為報錯ORA-04030,記憶體分配不足,原始碼是1億條提交,現改為1000000提交試下;
          分成10次提交,用繫結變數方式執行,此PLSQL塊執行10次,看是否還會報ORA-04030錯誤
            --1,以大資料量測試NUMBER型別的INSERT
                         --因為一條條插入太慢,採用1萬條一提交
                         --1萬條一提交仍是INSERT太慢,採用FORALL試下速度如下
                      DECLARE
                        V_LOWER NUMBER;--下界
                        V_UPPER NUMBER;
                        TYPE TYP_TAB_UPPER IS TABLE OF NUMBER index by BINARY_INTEGER;
                        TYP_TAB_UPPER_1 TYP_TAB_UPPER;
                       
                      BEGIN
                       V_LOWER:=1;
                       V_UPPER:=V_LOWER+&V*10000000-1;--上界,上界依賴於下界,二者相差1000000條記錄
                       for i in V_LOWER..V_UPPER loop
                        TYP_TAB_UPPER_1(I):=I;
                       end loop;
                      
                       FORALL I IN V_LOWER..V_UPPER
                         INSERT INTO T_NUMBER VALUES(TYP_TAB_UPPER_1(I));
                         COMMIT;
                       --END LOOP;
                      END;
                      已用時間:  00: 00: 17.34
                     
                      --如果提交1億條記錄就報下述錯誤,我昨天已經提高了SGA和PGA的大小,環境是11G R2,仍報錯
                       第 1 行出現錯誤:
                       ORA-06500: PL/SQL: 儲存錯誤
                       ORA-04030: 在嘗試分配 16356 位元組 (koh-kghu call ,pmucalm coll) 時程式記憶體不足
                       ORA-06512: 在 line 8
                     
                      --上述程式碼繫結變數總出錯,整體不好排錯,故只單獨把出錯的繫結變數拿出來
                      --經分析,是因為;寫成;了,所以一定要小心
                      SET SERVEROUTPUT ON
                      DECLARE
                      V_LOWER NUMBER;
                      V_UPPER NUMBER;
                      BEGIN
                       V_LOWER:=1;
                       V_UPPER:=V_LOWER+&I*100;
                       DBMS_OUTPUT.PUT_LINE(V_LOWER||'__'||V_UPPER);
                      END;
                     
                      --用普通的FOR LOOP提交1千萬看下效能
                       09:39:42 SQL> DECLARE
                       09:39:44   2                        BEGIN
                       09:39:44   3                         FOR I IN 1..10000000 LOOP
                       09:39:44   4                           INSERT INTO T_NUMBER VALUES(I);
                       09:39:44   5                         END LOOP;
                       09:39:44   6                        END;
                       09:39:45   7  /
                      
                       PL/SQL 過程已成功完成。
                      
                       已用時間:  00: 05: 39.37
                      
                       --小結
                          1,FORALL執行INSERT 1千萬用時17秒
                             FOR LOOP執行INSERT 1千萬用時5分鐘
                          2,二者差距相當大,20倍之差,所以大資料量操作一定要用FORALL
                          3,FORALL的語句如何讓它更快,要反思的地方
                         
            --2,以大資料量測試INTEGER型別的INSERT
                      DECLARE
                        V_LOWER INTEGER;--下界
                        V_UPPER INTEGER;
                        TYPE TYP_TAB_UPPER IS TABLE OF INTEGER index by BINARY_INTEGER;
                        TYP_TAB_UPPER_1 TYP_TAB_UPPER;
                       
                      BEGIN
                       V_LOWER:=1;
                       V_UPPER:=V_LOWER+&V*10000000-1;--上界,上界依賴於下界,二者相差1000000條記錄
                       for i in V_LOWER..V_UPPER loop
                        TYP_TAB_UPPER_1(I):=I;
                       end loop;
                      
                       FORALL I IN V_LOWER..V_UPPER
                         INSERT INTO T_NUMBER VALUES(TYP_TAB_UPPER_1(I));
                         COMMIT;
                       --END LOOP;
                      END;
                      已用時間:  00: 00: 22.32
                     
                     
                     
                      --3,以大資料量測試PLS_INTEGER型別的INSERT
                      DECLARE
                        V_LOWER PLS_INTEGER;--下界
                        V_UPPER PLS_INTEGER;
                        TYPE TYP_TAB_UPPER IS TABLE OF PLS_INTEGER index by BINARY_INTEGER;
                        TYP_TAB_UPPER_1 TYP_TAB_UPPER;
                       
                      BEGIN
                       V_LOWER:=1;
                       V_UPPER:=V_LOWER+&V*10000000-1;--上界,上界依賴於下界,二者相差1000000條記錄
                       for i in V_LOWER..V_UPPER loop
                        TYP_TAB_UPPER_1(I):=I;
                       end loop;
                      
                       FORALL I IN V_LOWER..V_UPPER
                         INSERT INTO T_NUMBER VALUES(TYP_TAB_UPPER_1(I));
                         COMMIT;
                       --END LOOP;
                      END;  
                      已用時間:  00: 00: 16.93
                     
                     
                      --4,以大資料量測試BINARY_INTEGER型別的INSERT
                      DECLARE
                        V_LOWER BINARY_INTEGER;--下界
                        V_UPPER BINARY_INTEGER;
                        TYPE TYP_TAB_UPPER IS TABLE OF BINARY_INTEGER index by BINARY_INTEGER;
                        TYP_TAB_UPPER_1 TYP_TAB_UPPER;
                       
                      BEGIN
                       V_LOWER:=1;
                       V_UPPER:=V_LOWER+&V*10000000-1;--上界,上界依賴於下界,二者相差1000000條記錄
                       for i in V_LOWER..V_UPPER loop
                        TYP_TAB_UPPER_1(I):=I;
                       end loop;
                      
                       FORALL I IN V_LOWER..V_UPPER
                         INSERT INTO T_NUMBER VALUES(TYP_TAB_UPPER_1(I));
                         COMMIT;
                       --END LOOP;
                      END;   
                      已用時間:  00: 00: 21.61
                     
                     
                     
                      --5,以大資料量測試BINARY_FLOAT型別的INSERT
                      DECLARE
                        V_LOWER BINARY_FLOAT;--下界
                        V_UPPER BINARY_FLOAT;
                        TYPE TYP_TAB_UPPER IS TABLE OF BINARY_FLOAT index by BINARY_INTEGER;
                        TYP_TAB_UPPER_1 TYP_TAB_UPPER;
                       
                      BEGIN
                       V_LOWER:=1;
                       V_UPPER:=V_LOWER+&V*10000000-1;--上界,上界依賴於下界,二者相差1000000條記錄
                       for i in V_LOWER..V_UPPER loop
                        TYP_TAB_UPPER_1(I):=I;
                       end loop;
                      
                       FORALL I IN V_LOWER..V_UPPER
                         INSERT INTO T_NUMBER VALUES(TYP_TAB_UPPER_1(I));
                         COMMIT;
                       --END LOOP;
                      END;   
                      已用時間:  00: 00: 21.35
                     
                      小結:最快是PLS_INTEGER;最慢的是INTEGER;

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/9240380/viewspace-743426/,如需轉載,請註明出處,否則將追究法律責任。

相關文章