gpt4 book ai didi

oracle - 与 Number 相比,Pls_integer 值需要 "less"存储空间。如何验证?

转载 作者:行者123 更新时间:2023-12-04 17:57:02 26 4
gpt4 key购买 nike

版本: 11.2.0.2.0

我想验证我在手册中再次阅读的以下断言:

The PLS_INTEGER data type has these advantages over the NUMBER data type and NUMBER subtypes:

PLS_INTEGER values require less storage.


我正在寻找有效使用的字节。

我知道 Oracle 内置数据类型和 PL/SQL 数据类型。
我再次阅读了文档中的特定部分:

Oracle data types

PL/SQL data types

我回顾了一些有用的函数: viszedump (等等:length、lengthb)。
我已经在这里和其他论坛/博客中搜索过,即使这在过去似乎是显而易见的事情,但我还是有点卡住了。

我的虚拟 程序 (visize 函数不会显示 pls_integer 的任何有效值,因为 Tony Andrews 在他的回答中说明了 原因 (注释 13/07/1)
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

按照文档:

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 大小的常量(如文档所说的 32 位)重写前面的过程, 我们可以在下面看到它不是

    我想这是由于数据类型“数字”的 内部表示
  • 但是 OP 是“ 如何验证

  • 使用 Tony Andrews 给出的“ great ”建议,并加载两个不同大小的数组(pls_integer 和 number),似乎:
  • 使用需要不同/相等存储的不同数字(前面提到的过程“TestSize”的输出)
  • pl/sql中使用varray实现数组
  • 测试这些数组的不同维度 10 000, 100 000
  • 100 000 个数字的大型数组比 pls_integer 需要更多的空间

  • PS 显然,这种方法 并不完全准确 (就像托尼在他的帖子中写的那样) 并与我的虚拟程序的输出相冲突,提供“Test20456079”方法的“大小” vsize for number) 是正确的!

    最后,我很少在我的生产代码中使用超过 100/200 个元素 的数组,只使用 以避免使 PGA 过载。
    对于这个维度,疑问依然存在!

    我必须做的其他研究才能发现这个“神谕”,这超出了我的知识范围;但出于这个原因,我写了这个问题! :-)

    过程 使用新的“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 是“ 如何验证

  • 使用 **Tony Andrews 给出的“ great ”建议

    虚拟程序“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'

    注释结果
                                             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

    最佳答案

    VSIZE function 不会显示任何差异,因为它是一个只能采用 NUMBER、DATE 或 VARCHAR2 值的重载函数(请参阅 SYS.STANDARD 的规范)。因此,当您传递 PLS_INTEGER 值时,该值首先隐式转换为 NUMBER。

    definition的 PLS_INTEGER 说

    The PLS_INTEGER data type stores signed integers in the range -2,147,483,648 through 2,147,483,647, represented in 32 bits.



    所以它总是 32 位 = 4 字节。然而,正如您所展示的,NUMBER 的 VSIZE() 可以超过 4 个字节:
    SQL> select vsize(2147483647) v from dual;

    v
    -
    6

    您可能会看到差异的一种方法是,如果您运行一些 PL/SQL 来填充内存中的大量 NUMBERS,并在之后查看 session 的 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';

    关于oracle - 与 Number 相比,Pls_integer 值需要 "less"存储空间。如何验证?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6622634/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com