TimesTen中应尽量使用CHAR替代VARCHAR2类型

在TimesTen SQL Reference中,Data Type|Storage Requirement一节,对于VARCHAR2类型有以下的描述:

For NOT INLINE columns:
On 64-bit platforms, length of value + 24 bytes (minimum of 40 bytes). NULL value is stored as (null bit) + 8 bytes, or 8.125 bytes.
This storage principal holds for all variable length NOT INLINE data types: TT_VARCHAR, TT_NVARCHAR, VARCHAR2, NVARCHAR2, and VARBINARY.
For INLINE columns:
On 32-bit platforms, n + 4 bytes. NULL value is stored as (null bit) + n + 4 bytes.
On 64-bit platforms, n + 8 bytes. NULL value is stored as (null bit) + n + 8 bytes.

这段花说明了,变长类型VARCHAR2如果是inline,对比于CHAR,没有任何空间节省,而且会多出许多空间开销,见下例(测试平台为32位):

create table iline(
a char(8)
);
begin
    for i in 1..1000000 loop
        insert into iline values('inline');
    end loop;
end;
Command> call ttComputeTabSizes('inline');
Command> tablesize iline;

Sizes of ORACLE.ILINE:

  INLINE_ALLOC_BYTES:   27442768
  NUM_USED_ROWS:        1000000
  NUM_FREE_ROWS:        192
  AVG_ROW_LEN:          27
  OUT_OF_LINE_BYTES:    0
  METADATA_BYTES:       69548
  TOTAL_BYTES:          27512316
  LAST_UPDATED:         2016-04-03 00:33:32.000000

1 table found.

上表定义了一个定长列,分配了27442768字节,平均行长度为27。
下例中,将char(8)改为varchar2(8),插入同样的数据

create table ooline(
a varchar2(8)
);
begin
    for i in 1..1000000 loop
        insert into ooline values('inline');
    end loop;
end;
/
Command> call ttComputeTabSizes('ooline');                                Command> tablesize ooline;                                                
Sizes of ORACLE.OOLINE:

  INLINE_ALLOC_BYTES:   31443536
  NUM_USED_ROWS:        1000000
  NUM_FREE_ROWS:        192
  AVG_ROW_LEN:          31
  OUT_OF_LINE_BYTES:    0
  METADATA_BYTES:       69536
  TOTAL_BYTES:          31513072
  LAST_UPDATED:         2016-04-03 00:38:03.000000

1 table found.

分配了31443536字节,平均行长度为31,恰好多了4个字节

drop table ooline;
create table ooline(
a varchar2(8)
);
begin
    for i in 1..1000000 loop
        insert into ooline values('ool');
    end loop;
end;
Command> call ttComputeTabSizes('ooline');                                     Command> tablesize ooline;                                                     
Sizes of ORACLE.OOLINE:

  INLINE_ALLOC_BYTES:   31443536
  NUM_USED_ROWS:        1000000
  NUM_FREE_ROWS:        192
  AVG_ROW_LEN:          31
  OUT_OF_LINE_BYTES:    0
  METADATA_BYTES:       69536
  TOTAL_BYTES:          31513072
  LAST_UPDATED:         2016-04-03 00:42:50.000000

1 table found.

减少插入数据的长度,由’inline’改为’ool’,结果一样,说明在inline模式下,占用的空间与插入数据的长度无关

将存储方式改为not inline

create table ooline(
a varchar2(8) not inline
);
begin
    for i in 1..1000000 loop
        insert into ooline values('ool');
    end loop;
end;
Command> call ttComputeTabSizes('ooline');                                     Command> tablesize ooline;                                                     
Sizes of ORACLE.OOLINE:

  INLINE_ALLOC_BYTES:   23442000
  NUM_USED_ROWS:        1000000
  NUM_FREE_ROWS:        192
  AVG_ROW_LEN:          47
  OUT_OF_LINE_BYTES:    24000008
  METADATA_BYTES:       69548
  TOTAL_BYTES:          47511556
  LAST_UPDATED:         2016-04-03 00:59:36.000000

1 table found.

强制将varchar2设置为not in line, 可以看出,虽然inline的分配少了,但总的字节多了。

以下是一个长度为256字节的VARCHAR2和CHAR的对比

create table iline(
a char(256)
);
begin
    for i in 1..10000 loop
        insert into iline values('inline');
    end loop;
end;
Command> call ttComputeTabSizes('iline');Command> tablesize iline;
Sizes of ORACLE.ILINE:

  INLINE_ALLOC_BYTES:   2820480
  NUM_USED_ROWS:        10000
  NUM_FREE_ROWS:        240
  AVG_ROW_LEN:          275
  OUT_OF_LINE_BYTES:    0
  METADATA_BYTES:       5228
  TOTAL_BYTES:          2825708
  LAST_UPDATED:         2016-04-03 01:12:20.000000

1 table found.

大于128字节,变长类型out-of-line存放

create table ooline(
a varchar2(256)
);
begin
    for i in 1..10000 loop
        insert into ooline values('inline');
    end loop;
end;
Command> call ttComputeTabSizes('ooline');                                Command> tablesize ooline;                                                
Sizes of ORACLE.OOLINE:

  INLINE_ALLOC_BYTES:   240000
  NUM_USED_ROWS:        10000
  NUM_FREE_ROWS:        240
  AVG_ROW_LEN:          47
  OUT_OF_LINE_BYTES:    240000
  METADATA_BYTES:       5216
  TOTAL_BYTES:          485216
  LAST_UPDATED:         2016-04-03 01:13:50.000000

1 table found.

可以看出,对于>128字节的varchar2,由于是out-of-line存放,存储效率高于char。

因此,长度较短的VARCHAR2类型应使用CHAR替代。只有在长度较长时,才考虑使用not inline的VARCHAR2,以节省空间。从性能计,也应尽量使用CHAR类型。而在Oracle中,由于存储方式的不同,应尽量使用VARCHAR2替代CHAR。

你可能感兴趣的:(inline,varchar2,dataType,timesten,outofline)