我的新项目的一个指导方针是指定精度&与Oracle PL \ SQL中的NUMBER一起扩展。开发人员手册说如果没有指定,则为每个变量分配22个字节的默认大小。
虽然我知道指定精度和重要性是很重要的。如果没有提供精度,我似乎并不同意分配22个字节。
http://docs.oracle.com/cd/B28359_01/server.111/b28318/datatype.htm#CNCPT1834
来自oracle docs:
" 内部数字格式
Oracle数据库以可变长度格式存储数字数据。每个值都以科学计数法存储,1个字节用于存储指数,最多20个字节用于存储尾数。结果值限制为38位精度。 Oracle数据库不存储前导零和尾随零。例如,数字412以类似于4.12×102的格式存储,其中1个字节用于存储指数(2),2个字节用于存储尾数(4,1,2)的三个有效数字。负数包括其长度的符号。"
我将上述文档发送给数据库架构师,但他似乎并不认同我。
如果我们不指定精度& oracle pl \ sql中NUMBER数据类型的比例是需要22个字节还是只有足够的字节来存储分配给它的值?
答案 0 :(得分:1)
NUMBER
相当于NUMBER(*)
。精度和比例仅限于可接受的值,并且不会影响内存分配。
HUSQVIK@HQ_PDB_TCP> DECLARE
2 item_count CONSTANT NUMBER := 10000000;
3 TYPE t_collection IS TABLE OF NUMBER(38);
4 data t_collection := t_collection();
5
6 PROCEDURE print_allocated_memory IS
7 allocated_memory NUMBER;
8 BEGIN
9 SELECT
10 value INTO allocated_memory
11 FROM
12 v$statname
13 JOIN v$mystat ON v$statname.statistic# = v$mystat.statistic#
14 WHERE
15 name = 'session pga memory';
16
17 dbms_output.put_line('Allocated memory: ' || round(allocated_memory / 1048576, 1) || ' MB');
18 END;
19 BEGIN
20 print_allocated_memory;
21
22 data.extend(item_count);
23
24 print_allocated_memory;
25
26 FOR i IN 1..item_count LOOP
27 data(i) := 1.00000000000000000000000000000000000011;
28 END LOOP;
29
30 print_allocated_memory;
31 END;
32 /
Allocated memory: 3.5 MB
Allocated memory: 483.8 MB
Allocated memory: 483.8 MB
PL/SQL procedure successfully completed.
Elapsed: 00:00:01.04
HUSQVIK@HQ_PDB_TCP>
您可以尝试NUMBER约束并查看它对内存分配没有影响在实际设置任何值之前分配内存,之后它不会更改。在示例中,集合中的一个条目大约是48个字节,但我预计集合条目本身会有一些显着的开销。
关联数组和嵌套表分配相同的空间(所以我希望嵌套表在内部实现与关联数组(B-tree)相同),VARRAY我得到410 MB所以它的效率稍高(也更快) )。
答案 1 :(得分:1)
但他似乎并不认同我。
向他展示vsize
功能的文档:http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions213.htm#i80071
VSIZE 返回内部表示中的字节数 EXPR。如果expr为null,则此函数返回null。
简单地证明他412占用3个字节,而-412占用4个字节:
select vsize( 412), vsize( -412) from dual;
VSIZE(412) VSIZE(-412)
---------- ---------------------------------------
3 4
另一项测试证明@Husquick的回答是正确的:
select vsize( 0.00000000000000000000000000000000000011 ),
vsize( 1.00000000000000000000000000000000000011)
from dual;
VSIZE(0.0000000000000000000000000000000 VSIZE(1.0000000000000000000000000000000
--------------------------------------- ---------------------------------------
2 21