2011-07-08 25 views
5

版本:11.2.0.2.0與數字相比,Pls_integer值需要「少」存儲。如何驗證?

我想驗證後續的說法,我在手冊中再次閱讀:

的PLS_INTEGER數據類型有過許多這樣的 優勢數據類型 和NUMBER亞型:

PLS_INTEGER values require less storage. 

我正在尋找有效使用的字節。

我知道Oracle內置的數據類型和PL/SQL數據類型。 我的文檔中再次讀取特定章節:

Oracle data types

PL/SQL data types

我查看了一些有用的功能:viszedump(依此類推:長度,LENGTHB)。 我在這裏和其他論壇/博客上搜索過,即使它看起來是一個明顯的東西,但我有點卡住了。


我的虛擬程序(visize功能不會爲PLS_INTEGER表現出任何有效的值,因爲下面在他的回答由託尼·安德魯斯所示的理由(請注意13/07/11)

create or replace procedure TestSize 
(
    testPlsInteger in pls_integer 
    ,testNumber  in number 
) is 
    sizePlsInteger pls_integer; 
    sizeNumber  pls_integer; 
    FORMAT_DIM constant pls_integer := 15; 
begin 
    select vsize(testPlsInteger), vsize(testNumber) 
    into sizePlsInteger, sizeNumber 
    from dual; 

    dbms_output.put_line('number:' || rpad(testPlsInteger, FORMAT_DIM) 
         ||' PLS_INTEGER SIZE:' || rpad(sizePlsInteger, FORMAT_DIM) 
         || ' NUMBER SIZE:' || sizeNumber); 
end; 

測試

begin 
    TestSize(2147483647, 2147483647); 
    TestSize(1, 1); 
    TestSize(1000000, 1000000); 
    TestSize(12345678, 12345678); 
end; 

個結果

number:2147483647  PLS_INTEGER SIZE:6    NUMBER SIZE:6 
number:1    PLS_INTEGER SIZE:2    NUMBER SIZE:2 
number:1000000   PLS_INTEGER SIZE:2    NUMBER SIZE:2 
number:12345678  PLS_INTEGER SIZE:5    NUMBER SIZE:5 

- 增加13/07/2011

>>>>>>>>> NEW節中的文檔:

The PLS_INTEGER data type has these advantages over the NUMBER data type and NUMBER subtypes: 
PLS_INTEGER values require less storage. 

The PLS_INTEGER data type stores signed integers in the range -2,147,483,648 through 2,147,483,647, represented in 32 bits. 
  • 文檔斷言 「PLS_INTEGER值需要存儲」 並非總是如此。

應該是真的,數字數據類型應該比pls_integer需要更多的空間。 使用pls_integer大小的常量(類似於doc的32位)重寫前面的過程,我們可以在下面看到它不是真的

我想這是由於數據類型「數字」

  • 內部表示但OP是「如何驗證

使用「 「建議由給出託尼安德魯斯,並加載兩個不同大小的數組(pls_integer和數字),似乎是:

  1. 使用需要不同/等於存儲不同數目(先前提到的過程「TestSize」的輸出)
  2. 使用VARRAY實現在PL/SQL陣列
  3. 測試不同尺寸爲這些陣列10 000, 100 000
  4. 100,000個數字的大數組需要比pls_integer更多的空間

PS顯然,這種方法是不完全準確的(像託尼在他的帖子中寫道),並與我的虛擬程序「TestSize」的輸出衝突,提供的方法來計算數字「TestSize」中的大小(vsize爲數字)是正確的!

最後,我很少在我的生產代碼中使用超過100/200元素的陣列,只是避免超負荷PGA。 而對於這個尺寸的疑問依然存在!

其他研究我不得不去發現這個「oracle」,這超出了我的理解;但爲此我寫了這個問題! :-)


步驟使用新的 「Testsize」 程序。

文檔斷言「PLS_INTEGER值要求減去存儲」並非總是如此。

create or replace procedure TestSize 
(
    testNumber  in number 
) is 
    sizeNumber  pls_integer; 

    SIZE_PLS_INTEGER constant pls_integer:= 4; -- always 32 bits(4 bytes) 
    FORMAT_DIM constant pls_integer := 15; 
    FORMAT_MINOR constant varchar2(1) := '<'; 
    FORMAT_EQUAL constant varchar2(1) := '='; 

begin 
    select vsize(testNumber) 
    into sizeNumber 
    from dual; 

    dbms_output.put_line('number:' || rpad(testNumber, FORMAT_DIM) 
         ||' PLS_INTEGER SIZE:' 
         || case when (SIZE_PLS_INTEGER<sizeNumber) then 
            rpad(SIZE_PLS_INTEGER, FORMAT_DIM,FORMAT_MINOR) 
           when (SIZE_PLS_INTEGER=sizeNumber) then 
            rpad(SIZE_PLS_INTEGER, FORMAT_DIM,FORMAT_EQUAL) 
           else rpad(SIZE_PLS_INTEGER, FORMAT_DIM) 
          end 
         || ' NUMBER SIZE:' 
         || case when (sizeNumber<SIZE_PLS_INTEGER) then 
             rpad(sizeNumber,FORMAT_DIM,FORMAT_MINOR) 
           else rpad(sizeNumber,FORMAT_DIM) 
          end); 
end TestSize; 

測試

begin 
    TestSize(2147483647); 
    TestSize(1); 
    TestSize(10); 
    TestSize(100); 
    TestSize(1000); 
    TestSize(1000); 
    TestSize(100000); 
    TestSize(1000000); 
    TestSize(10000000); 
    TestSize(10000000); 
    TestSize(100000000); 
    TestSize(1000000000); 
    TestSize(1000000000); 
    TestSize(90000000); 
    TestSize(9923); 
    TestSize(99232); 
    TestSize(555555); 
    TestSize(12345); 
    TestSize(1234); 
    TestSize(1000001); 
    TestSize(20000000000); 
    TestSize(12345678); 
    TestSize(12345678); 
end; 

結果

number:2147483647  PLS_INTEGER SIZE:4<<<<<<<<<<<<<< NUMBER SIZE:6    
number:1    PLS_INTEGER SIZE:4    NUMBER SIZE:2<<<<<<<<<<<<<< 
number:10    PLS_INTEGER SIZE:4    NUMBER SIZE:2<<<<<<<<<<<<<< 
number:100    PLS_INTEGER SIZE:4    NUMBER SIZE:2<<<<<<<<<<<<<< 
number:1000   PLS_INTEGER SIZE:4    NUMBER SIZE:2<<<<<<<<<<<<<< 
number:1000   PLS_INTEGER SIZE:4    NUMBER SIZE:2<<<<<<<<<<<<<< 
number:100000   PLS_INTEGER SIZE:4    NUMBER SIZE:2<<<<<<<<<<<<<< 
number:1000000   PLS_INTEGER SIZE:4    NUMBER SIZE:2<<<<<<<<<<<<<< 
number:10000000  PLS_INTEGER SIZE:4    NUMBER SIZE:2<<<<<<<<<<<<<< 
number:10000000  PLS_INTEGER SIZE:4    NUMBER SIZE:2<<<<<<<<<<<<<< 
number:100000000  PLS_INTEGER SIZE:4    NUMBER SIZE:2<<<<<<<<<<<<<< 
number:1000000000  PLS_INTEGER SIZE:4    NUMBER SIZE:2<<<<<<<<<<<<<< 
number:1000000000  PLS_INTEGER SIZE:4    NUMBER SIZE:2<<<<<<<<<<<<<< 
number:90000000  PLS_INTEGER SIZE:4    NUMBER SIZE:2<<<<<<<<<<<<<< 
number:9923   PLS_INTEGER SIZE:4    NUMBER SIZE:3<<<<<<<<<<<<<< 
number:99232   PLS_INTEGER SIZE:4============== NUMBER SIZE:4    
number:555555   PLS_INTEGER SIZE:4============== NUMBER SIZE:4    
number:12345   PLS_INTEGER SIZE:4============== NUMBER SIZE:4    
number:1234   PLS_INTEGER SIZE:4    NUMBER SIZE:3<<<<<<<<<<<<<< 
number:1000001   PLS_INTEGER SIZE:4<<<<<<<<<<<<<< NUMBER SIZE:5    
number:20000000000  PLS_INTEGER SIZE:4    NUMBER SIZE:2<<<<<<<<<<<<<< 
number:12345678  PLS_INTEGER SIZE:4<<<<<<<<<<<<<< NUMBER SIZE:5    
number:12345678  PLS_INTEGER SIZE:4<<<<<<<<<<<<<< NUMBER SIZE:5    

  • 的OP是「如何驗證

使用」 TestSize2 「偉大」由**託尼·安德魯斯

啞過程給出的建議「

create or replace procedure testSize2 
(
    testNum  in pls_integer 
    ,maxDim  in pls_integer 
    ,secondsToWait in pls_integer 
) is 
    type TPlsIntegers is varray(100000) of pls_integer; 
    type TNumbers is varray(100000) of number; 
    pls  TPlsIntegers := TPlsIntegers(); 
    numbers TNumbers := TNumbers(); 

    MODULE  constant varchar2(20) := 'TestSize2'; 
    PLS_ACTION constant varchar2(20) := 'pls_integer'; 
    NUMBER_ACTION constant varchar2(20) := 'number'; 
    SEP   constant varchar2(3) := ' - '; 

begin 
    dbms_application_info.set_action(action_name => PLS_ACTION||SEP||testNum ||SEP||maxDim); 

    pls.extend(maxDim); 
    for cont in 1 .. maxDim 
    loop 
     pls(cont) := testNum; 
    end loop; 
    dbms_lock.sleep(seconds => secondsToWait); 

    -- check pga with query 
    dbms_application_info.set_action(action_name => NUMBER_ACTION||SEP||testNum ||SEP||maxDim); 
    numbers.extend(maxDim); 
    for cont in 1 .. maxDim 
    loop 
     numbers(cont) := testNum; 
    end loop; 

    -- check pga with query 
    DBMS_LOCK.sleep(secondsToWait); 
end; 

測試

declare 
    MAX_TO_WAIT constant pls_integer := 3; 
    MODULE  constant varchar2(30) := 'testSize2'; 
begin 
    debug.disable; 
    dbms_application_info.set_module(MODULE, action_name => ''); 
    testSize2(testNum => 90000000, secondsToWait => MAX_TO_WAIT, maxDim => 100); 
    testSize2(testNum => 90000000, secondsToWait => MAX_TO_WAIT, maxDim => 10000); --10 000 
    testSize2(testNum => 90000000, secondsToWait => MAX_TO_WAIT, maxDim => 100000); --100 000  

    testSize2(testNum => 12345, secondsToWait => MAX_TO_WAIT, maxDim => 10000); --10 000  
    testSize2(testNum => 12345, secondsToWait => MAX_TO_WAIT, maxDim => 100000); --100 000 

    testSize2(testNum => 2147483647, secondsToWait => MAX_TO_WAIT, maxDim => 100); 
    testSize2(testNum => 2147483647, secondsToWait => MAX_TO_WAIT, maxDim => 10000); --10 000 
    testSize2(testNum => 2147483647, secondsToWait => MAX_TO_WAIT, maxDim => 100000); --100 000*\*\*/ 

    dbms_application_info.set_action(action_name => 'END'); 
end; 

查詢監視PGA

select vsst.sid || ',' || vses.serial# username, vsst.value,vses.MODULE,vses.ACTION 
from v$sesstat vsst, v$statname vstt, v$session vses 
where vstt.statistic# = vsst.statistic# 
and vsst.sid = vses.sid 
and vstt.name = 'session pga memory' 
and vses.username = 'HR' 
and vses.MODULE = 'testSize2' 

Annoted結果

          pls_integer  number  dif 
--           size  size  size 
-- n=90000000   DIM aRRAY= 100  528612  594148< DIF= 65536 
-- n=90000000   DIM aRRAY= 10000 725220  1118436< DIF= 393216 
-- n=90000000   DIM aRRAY= 100000 2101476  5771492> DIF= 3670016 

-- n=12345    DIM aRRAY= 10000 921828  1380580< DIF= 458752 
-- n=12345    DIM aRRAY= 100000 2101476  5771492> DIF= 3670016 

-- n=2147483647  DIM aRRAY= 100  790756  856292 < DIF= 65536 
-- n=2147483647  DIM aRRAY= 10000 921828  1380580< DIF= 458752 
-- n=2147483647  DIM aRRAY= 100000 2101476  5771492> DIF= 3670016 
+0

新增欄目13/07/2011 – zep

回答

8

VSIZE功能將不顯示任何差異,因爲它是一個重載函數,可以採取數字,日期或VARCHAR2值只有(請參閱SYS.STANDARD的規格)。所以當你傳遞一個PLS_INTEGER值時,該值首先被隱式轉換爲NUMBER。

PLS_INTEGER的definition

的PLS_INTEGER數據類型存儲 範圍符號整數 2,147,483,648到2,147,483,647,在32位表示。

所以它總是32位= 4個字節。然而,當你顯示,數字的VSIZE()可超過4個字節:

SQL> select vsize(2147483647) v from dual; 

v 
- 
6 

一種方式你可以看到不同的是,如果你運行一些PL/SQL用於填充一個大陣內存中的NUMBERS,並在之前查看會話的PGA使用情況。然後重複PLS_INTEGER。你可以用小的和大的值重複實驗等等。 (警告:PGA是具有一定規模的大塊來分配,所以這不會是完全準確的,但一個足夠大的陣列可以顯示任何顯著差異。)

要監控PGA的使用使用的查詢,如:

select vsst.sid||','||vses.serial# username, 
     vsst.value 
from v$sesstat vsst, v$statname vstt, v$session vses 
where vstt.statistic# = vsst.statistic# 
and vsst.sid = vses.sid 
and vstt.name = 'session pga memory' 
and vses.username = 'MYUSER'; 
+0

+1謝謝。有沒有辦法來驗證pls_integer的大小,或者我必須接受32位才能看到它。 – zep

+0

謝謝。好的,我已經看到了更新,這意味着有時候PLS_INTEGER需要比NUMBER更多的字節,比如數字1? – zep

+1

是的,我認爲是 - 看到上述最新更新的方法來看到不同之處。 –

相關問題