创建表时考虑列的顺序

原创 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值的列可以放在最后面.可以终合考虑上面两点,根据系统的应用做相应操作.

数据结构中散列表的复习笔记

除了各种树表之外,还可以采用散列技术来表示并实现动态查找表。“散列”既是一种存储方式,又是一种查找方法。这种查找方法称为散列查找。按散列存储方式构造的存储结构称为散列表。散列技术的核心是散列函数。 ...
  • u014488381
  • u014488381
  • 2014年12月18日 21:31
  • 912

顺序表的建立,实现及操作

#include #include #include #include #include #define MAX 1000+5 using namespace std; typedef struct ...
  • bengshakalakaka
  • bengshakalakaka
  • 2017年03月15日 18:37
  • 1473

数据存储结构---顺序 链式 索引 散列

存储结构分四类:顺序存储、链接存储、索引存储和散列存储。 顺序结构和链接结构适用在内存结构中。 索引结构和散列结构适用在外存与内存交互结构。 顺序存储:在计算机中用一组地址连续的存储单元依次存储线...
  • bbs375
  • bbs375
  • 2016年09月11日 09:49
  • 1081

oracle 调整表字段顺序

--将想调整后的顺序新建一张表 -- Create table create table T_EVALUATION_GRADE_HIS1 ( ID NUMBER(11)...
  • lanqibaoer
  • lanqibaoer
  • 2015年05月15日 12:12
  • 892

C++中如何建立一个顺序表

准备数据 #define MAXLEN 100 //定义顺序表的最大长度 struct DATA { char key[10]; //结点的关键字 char name[20]; int ag...
  • QianShouYuZhiBo
  • QianShouYuZhiBo
  • 2013年09月25日 00:09
  • 5537

hbase javaapi 表定义和列族定义的具体含义

hbase是一个KeyValue型的数据库,在《hbase实战》描述它的逻辑模型【行键,列族,列限定符,时间版本】,物理模型是基于列族的。但实际情况是啥?还是上点代码吧。 HTableD...
  • qq_20641565
  • qq_20641565
  • 2017年02月22日 15:25
  • 1541

表连接的方法+使用表连接而不是多个表查询+from字句表的顺序

表连接的方法 使用表连接而不是多个表查询 1执行表连接比多个表查询效率更高,因为执行每条sql语句,oracle内部会执行很多工作。比如解析SQL语句,估算索引的利用率,绑定变量,读取数据块等,所...
  • zhou920786312
  • zhou920786312
  • 2017年06月04日 10:53
  • 592

仅当使用了列列表并且 IDENTITY_INSERT 为 ON 时,才能为表'stulnfo'中的标识列指定显式值。

插入数据时,自增长列是系统自动处理,不需要你来指定数值,你也指定不了。只有将IDENTITY_INSERT 为 ON 时插入数据时,自增长列你才可以指定一个值 比如我有一个表PZ,有如下列XH,ID,...
  • liyanlei5858
  • liyanlei5858
  • 2014年06月12日 17:41
  • 3763

C++ 容器(一):顺序容器简介

C++提供了使用抽象进行高效编程的方式,标准库中定义了许多容器类以及一系列泛型函数,使程序员可以更加简洁、抽象和有效地编写程序。本文分三部分将解包括:顺序容器,关联容器和泛型算法。...
  • YhL_Leo
  • YhL_Leo
  • 2015年08月18日 21:01
  • 4984

仅当使用了列的列表,并且IDENTITY_INSERT为ON时,才能在表'goldlog'中为标识列指定显式值

标题即问题;用VB.NET敲三层出现的这个问题,是在一些问题之后出现的,之前的问题大都是多打了一个字母,或者丢了一个letter造成的, 看来真是有些太马虎了,改改改!进入正题,下面是数据访问层的代码...
  • ma15732625261
  • ma15732625261
  • 2016年02月25日 17:23
  • 2602
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:创建表时考虑列的顺序
举报原因:
原因补充:

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