Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4478116
  • 博文数量: 109
  • 博客积分: 10011
  • 博客等级: 上将
  • 技术积分: 2457
  • 用 户 组: 普通用户
  • 注册时间: 2006-10-18 19:04
文章分类

全部博文(109)

文章存档

2011年(1)

2010年(10)

2009年(36)

2008年(62)

我的朋友

分类: Oracle

2009-08-31 10:07:12


在99%的应用中建立的普通的表叫堆组织表(HOT),我先说一下堆组织表是怎么样存储数据的,来看一个例子:
SQL> create table t_temp
  2  ( a int,
  3    b varchar2(4000) default rpad('*',4000,'*'),
  4    c varchar2(3000) default rpad('*',3000,'*')
  5  )
  6  /
表已创建。
SQL> insert into t_temp (a) values ( 1);
已创建 1 行。
SQL> insert into t_temp (a) values ( 2);
已创建 1 行。
SQL> insert into t_temp (a) values ( 3);
已创建 1 行。
SQL> delete from t_temp where a = 2 ;
已删除 1 行。
SQL> insert into t_temp (a) values ( 4);
SQL> select a from t_temp;
         A
----------
         1
         4
         3
   大家发现,全表扫描后的数据,并不是数据插入的顺序,一般来讲,HOT表的本质是无效的数据集合,只要有空间,数据可以放在任何地方。每当插入一条数据的时,ORACLE为数据分配一个BLOCK来存放这个数据,如果插入的第二条数据是一个大行,无法放在第一条数据所在的BLOCK上,ORACLE又会为这第二条数据分配一个BLOCK,在插入一条小行数据的时候,ORACLE如果发现第一个数据块可以存放,那就会放在第一个BLOCK里,那么通过全表扫描所有的BLOCK时,得到的数据顺序就是1,3,2的顺序了。
   上面的例子,做了DELETE a=2记录的以后,INSERT a=4记录时,ORACLE发现在原来存放2记录的BLOCK可以存放4,那么就放在那里了,所有结果是1,4,3。
   如果想按照插入的顺序排序得到数据,一般的做法是添加一个sequence生成的主键,模拟插入顺序,然后ORACLE会为组件建索引,然后order by它就可以了,但是大家不觉得这样麻烦吗?我们必须为HOT一个主键分配表空间和索引分配空间。索引组织表就不存在这个问题。
索引组织表(Index Organized Table ,IOT)
   IOT就是存储在索引结构中的表,在IOT中,索引就是数据,数据就是索引。我们不需要像HOT中花费大量的工作维护和管理索引。什么情况适合用IOT呢。举两个例子;
1:
create table keywords
( word varchar2(50),
position int,
doc_id int,
primary key(word,position,doc_id)
);
   在 此,我的表完全由主键组成。因此有超过100%的(主键索引)开销;表的大小与主键索引的大小相当(实际上,主键索引更大,因为它物理地存储了所指向的行 的rowid;而表中并不存储rowid,表中的行ID是推断出来的)。使用这个表时,WHERE子句只选择了WORD列或WORD和POSITION 列。也就是说,我并没有使用表,而只是使用了表上的索引,表本身完全是开销.这样的应用适合使用IOT。
   另一个适于使用IOT的实现是代码查找表。例如,可能要从ZIP_CODE查找STATE。此时可以不要堆表,而只使用IOT本身。如果你只会通过主键来访问一个表,这个表就非常适合实现为IOT。
 
IOT的优点:
1)提高缓冲区缓存效率,因为给定查询在缓存中需要的块更少。
2)减少缓冲区缓存访问
3)获取数据的工作总量更少,因为获取数据更快
4)每次查询完成的物理I/0更少,因为对于任何给定的查询,需要的块更少,而且对于地址记录的一个物理I/0很可能可以获取所有地址(而不只是其中的一个地址,而HOT就是只获取一个地址)
如何深入理解这些优点,我会在以后的文章谈到。。
 
 
 
 
 
阅读(1113) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~