创建表时考虑列的顺序

原创 2004年09月03日 11:20:00

创建表时考虑列的顺序
创建一个表时表中列的顺序在某些程度上对性能会有一定的影响.(表中的列有数据)
Oracle对行数据的存储结构ROW HEADER(行头)和COLUMN DATA(列数据).ROW HEADER存储的信息是一个FLAG BYTE,一个LOCK BYTE 和COLUMN

COUNT.COLUMN DATA包含COLUMN LENGTH和COLUMN DATA

关于这些我们可以DUMP个表做一下测试
create test as select * from dba_objects;
select header_file,header_block from dba_segments where owner='TEST' and segment_name='TEST';

HEADER_FILE    HEADER_BLOCK
------------------------   ---------------------------
                   13                      1179
alter system dump datafile 13 block 1180

得出来的文件在UDUMP中.我们查看如下信息
block_row_dump:
tab 0, row 0, @0x1f20
tl: 96 fb: --H-FL-- lb: 0x0  cc: 13--------row header信息.
col  0: [ 3]  53 59 53-------------------COLUMN DATA
fb: --H-FL-- 是FLAG BYTE. 
fb Flag Byte:
K = Cluster Key (Flags may change meaning if this is set to show HASH cluster)
C = Cluster table member
H = Head piece of row
D = Deleted row
F = First data piece
L = Last data piece
P = First column continues from previous piece
N = Last column continues in next piece
lb: 0x0-----------LOCK BYTE,锁信息
cc: 13------------COLUMN COUNT
col  0---------第一列
[ 3]-------------COLUMN LENGTH
  53 59 53---------实际数据

这里一些信息可以参考grassbell写的文章<<偷窥Data block 的物理结构>>.对每一个列,在每一个列数据前都含有列长度.在做查询时,查询行中某个

列的值,Oracle首先做的是检查这些相关列的长度位.这个操作比较快而且效率较高.但是如果反复频繁的这样子做还是会带来性能方面的影响.
下面的例子中创建了一个有10列的表并插入数据.
先设置DB_BLOCK_SIZE=2K(用参数设置,在这里设置为这个只是为了测试方便)
SQL> create table small (
  2    n0 number,
  3    n1 number,
  4    n2 number,
  5    n3 number,
  6    n4 number,
  7    n5 number,
  8    n6 number,
  9    n7 number,
 10    n8 number,
 11    n9 number
 12  ) pctfree 0;

Table created.

SQL> begin
  2    for i in 1..78 loop
  3      insert into small values (0,0,0,0,0,0,0,0,0,0);
  4    end loop;
  5  end;
  6  /

PL/SQL procedure successfully completed.

SQL> set timing on
SQL> declare
  2    n number;
  3  begin
  4    for i in 1..1000000 loop
  5      select sum(n0) into n from small;
  6    end loop;
  7  end;
  8  /

PL/SQL procedure successfully completed.

Elapsed: 00:07:437.30
SQL> declare
  2    n number;
  3  begin
  4    for i in 1..1000000 loop
  5      select sum(n9) into n from small;
  6    end loop;
  7  end;
  8  /

PL/SQL procedure successfully completed.

Elapsed: 00:08:482.13

从上面的例子很明显可以看到在一个表中做查询时,查询的数据和列的属性都是一样的,但是所查的列位于第一列时查询速度比在第10快了差不多

10%.所以在建表的时候规则就是根据应用将表中经常访问的列放面前面.建表时一般都有一个PRIMARY KEY的列,像这种属性的列一般我们直接访

问的并不多.所以我们一般不放在第一列.关于这个其实如果我们有注意到的话,Oracle本身字典内表也是这样子的.
desc dba_objects看看.或者其他的表可以试试.

还有另外一个要考虑的列的位置的就是列中含有较多的NULL值时所要放的位置.
Oracle存储NULL值时,一行中某个列存在NULL值,而这一列的后面的列中存在有数据(非NULL),则Oracle会分配1byte来存放NULL.如果这一列的后面

没有列或者都是NULL值时.这一列和后面的NULL值Oracle都不做存储.列信息也不存储.这一点可以看以下例子.

SQL> create table null_order (
  2    column1 number,
  3    column2 number,
  4    column3 number
  5  );

Table created.

SQL> insert into null_order (column2) values (0);

1 row created.

SQL> select header_file, header_block from dba_segments
  2  where segment_name = 'TEST' and owner = 'TEST';

HEADER_FILE HEADER_BLOCK
----------- ------------
          3        50010

SQL> alter system dump datafile 3 block 50011;

System altered.

然后查看DUMP出来的文件的相关信息
block_row_dump:
tab 0, row 0, @0x7b2
tl: 6 fb: --H-FL-- lb: 0x1 cc: 2
col  0: *NULL*--------------第一列的NULL
col  1: [ 1]  80----------------第二列的值(后面没有了第三列的值)
end_of_block_dump

结论:创建一个表时,可以将我们经常访问到的列放在表的前面.一般很少直接SELECT出来的PRIMARY KEY列可以放到中间来.列中如果可能会含有

较多NULL值的列可以放在最后面.可以终合考虑上面两点,根据系统的应用做相应操作.

【网络编程】数据传输时的字节序

前言可能小组的同学很早就听说过大小端,但是似乎这个顺序并没有什么卵用。。(我就是这么想的)不过在学习网络编程中,突然对这个问题有了新的认识,赶紧总结下,不然以后肯定踩坑。。。本文假定读者已经明白了大小...
  • XiyouLinux_Kangyijie
  • XiyouLinux_Kangyijie
  • 2017-06-10 16:15:06
  • 1044

修改Hibernate源码实现建表时字段和Entity里定义的fields顺序一致 -

Hibernate(至截稿时最新版本为4.1.3.Final)自动建表的表字段顺序总是随机的,之前我们总是自己写语句建好表,再使用Hibernate进行增删改查。始终是有点不方便。  最近看了下源码...
  • hkawei
  • hkawei
  • 2017-05-10 17:19:41
  • 729

mysql中创建表的注意事项和好的习惯

1.一定写注释            字段多了或者时间长了就很容易忘记每个字段的字段是用来做什么的。写注释是一个很好的习惯,不管是自己测试的表还是字段很少的表,时时刻刻养成好习惯。 2.字段长...
  • zhanglei500038
  • zhanglei500038
  • 2017-05-09 21:49:24
  • 389

SQL创建表时候添加字段说明方法

/* 在SQL语句中通过系统存储过sp_addextendedproperty可为表字段添加上动态的说明(备注)下面是SQL SERVER帮助文档中对sp_addextendedproperty存储...
  • kuaile211
  • kuaile211
  • 2014-07-14 10:19:25
  • 1474

ORACLE创建表时添加列说明

使用comment on,举个例子: create table EMP ( empid NUMBER ); comment on table EMP is '员工信息'; --添加表描述 ...
  • hmw1986
  • hmw1986
  • 2015-11-11 15:28:03
  • 390

关于hibernate通过注解方式自动生成表时字段的顺序问题

今天在使用hibernate3.0的annotation方式自动生成表时,发现生成表后总是插入不了记录(该记录按照entity实体的field顺序),仔细观察自动生成的表发现新表的字段顺序竟然和ent...
  • z893196569
  • z893196569
  • 2015-06-06 20:18:45
  • 4588

pg学习_基本表定义_创建表

创建表的语法结构 highgo=# \h create table Command: CREATE TABLE Description: define a new table Syntax: ...
  • qq_21127313
  • qq_21127313
  • 2017-03-31 22:53:01
  • 209

网络编程时的字节顺序变换,地址变换

写网络程序的时候经常会遇到网络字节顺序和
  • dliang27
  • dliang27
  • 2014-08-12 22:51:30
  • 242

oracle_建表并指定字段和描述

---建表 CREATE TABLE  tablename (   ID1            VARCHAR2(50) NOT NULL,   ID2            INTEGER   N...
  • ye1142262478
  • ye1142262478
  • 2016-04-29 17:05:47
  • 2775

sql server如何在用sql创建表时给表名以及列名添加注释?

sql如下: CREATE TABLE noteAdd( [Id_P] [int] NOT NULL, [LastName] [varchar](255)  NULL, [FirstName]...
  • suyu_yuan
  • suyu_yuan
  • 2016-09-30 15:42:24
  • 7237
收藏助手
不良信息举报
您举报文章:创建表时考虑列的顺序
举报原因:
原因补充:

(最多只允许输入30个字)