著名的Tanel Poder最近在他的博客上发表了《Which number takes more space in an Oracle row?》;Oracle是如何存储数字类型字段的?如果我们惯性思维的话,存储数字123肯定要比存储数字10000000000000000所占用的空间少吧,事实是这样吗?
SQL> select vsize(123) from dual; VSIZE(123) ---------- 3 SQL> select dump(123,16) from dual; DUMP(123,16) -------------------- Typ=2 Len=3: c2,2,18 /* 可以看到Oracle存储数字123需要用到3个字节的空间,其16进程形式为c2,02,18 */ /* 如果是gooooogle(1后面跟n个零)呢? * / SQL> select vsize(power(10,38)) from dual; VSIZE(POWER(10,38)) ------------------- 2
SQL> select dump(power(10,38),16) from dual; DUMP(POWER(10,38) ----------------- Typ=2 Len=2: d4,2 /* power(10,38)居然仅占用2个字节空间,其16进程形式为d4,02 */ /* 这是真的吗? * / /* 目前number类型最大为38位 */ SQL> create table YOUYUS (t1 number(38,0)) tablespace users; Table created. SQL> insert into YOUYUS values(123); 1 row created. SQL> select dump(power(10,37),16) from dual; DUMP(POWER(10,37) ----------------- Typ=2 Len=2: d3,b SQL> insert into YOUYUS values(power(10,37)); 1 row created. SQL> commit; Commit complete. SQL> alter system checkpoint; System altered. SQL> select header_block ,header_file from dba_segments where segment_name='YOUYUS'; HEADER_BLOCK HEADER_FILE ------------ ----------- 522 4 SQL> alter system dump datafile 4 block 523; System altered. block dump record: tl: 7 fb: --H-FL-- lb: 0x1 cc: 1 col 0: [ 3] c2 02 18 tab 0, row 1, @0x1f8b tl: 6 fb: --H-FL-- lb: 0x1 cc: 1 col 0: [ 2] d3 0b /* 可以看到power(10,37)的确只占用了2个字节 * /
Oracle存储数字类型的长度和数字的大小无关,而和数字字面值有关系,字面值越复杂空间占用往往越多:
SQL> select dump(power(10,38)+1,16) from dual; DUMP(POWER(10,38)+1,16) -------------------------------------------------------- Typ=2 Len=21: d4,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2 SQL> select dump(power(10,38)-1,16) from dual; DUMP(POWER(10,38)-1,16) ------------------------------------------------------------------------- Typ=2 Len=20: d3,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64
Comment