最近在学习PostgreSQL数据库,看到和Oracle及mysql-Innodb引擎的一些对比,其中有关堆表和索引组织表的描述,特意查了些资料整理如下:
PostgreSQL只支持堆表,不支持索引组织表
Oracle支持堆表,也支持索引组织表
Innodb只支持索引组织表
1. 堆组织表:
通常我们默认建的表就是堆组织表。
语法:Create table
test(
Id
int,
Name
varchar2(10)
);
此类型的表中,数据会以堆的方式进行管理,增加数据时候,会使用段中找到的第一个能放下
此数据的自由空间。当从表中删除数据时候,则允许以后的UPDATE和INSERT重用这部分空间,
它是以一种有些随机的方式使用。
很多初学者会想当然的以为数据的插入会按顺序进行,第一条肯定排在第一位,接着是第二条,一直到最后。
可当SELECT查询的时候,返回的结果往往让人失望。排列的顺序让人大跌眼镜,下面来看一个例子。
create table
t(
a
int,
b varchar2(4000) default
rpad('*', 4000,
'*'),
c varchar2(3000) default
rpad('*',
3000,'*')
);
insert into t(a) values
(1);
insert into t(a) values
(2);
insert into t(a) values
(3);
delete from t where
a=2;
insert into t(a) values
(4);
SQL> select a from
t;
A
----------
1
4
3
全表扫描时,会按命中的顺序来获取数据,而不是按插入的顺序。
这是一个必要要了解的重要的数据库概念。一般来说,数据库表本质上是无序的数据组合。
2. 索引组织表(index organized table,
IOT):就是存储在一个索引结构中的表,数据按主键进行存储和排序。
适用的场景:
a.完全由主键组成的表。这样的表如果采用堆组织表,则表本身完全是多余的开销,
因为所有的数据全部同样也保存在索引里,此时,堆表是没用的。
b.代码查找表。如果你只会通过一个主键来访问一个表,这个表就非常适合实现为IOT.
c.如果你想保证数据存储在某个位置上,或者希望数据以某种特定的顺序物理存储,IOT就是一种合适的结构。
IOT提供如下的好处:
·提高缓冲区缓存效率,因为给定查询在缓存中需要的块更少。
·减少缓冲区缓存访问,这会改善可扩缩性。
·获取数据的工作总量更少,因为获取数据更快。
·每个查询完成的物理I/O更少。
如果经常在一个主键或唯一键上使用between查询,也是如此。如果数据有序地物理存储,就能提升这些查询的性能。
语法:create
table indexTable(
ID varchar2
(10),
NAME varchar2
(20),
constraint pk_id primary key
(ID)
) organization index;
3. 索引聚簇表:
聚簇是指:如果一组表有一些共同的列,则将这样一组表存储在相同的数据库块中;聚簇还表示把相关的数据存储在同一个块上。
利用聚簇,一个块可能包含多个表
的数据。概念上就是如果两个或多个表经常做链接操作,那么可以把需要的数据预先存储在一起。
聚簇还可以用于单个表,可以按某个列将数据分组存储。
语法:
索引聚簇表是基于一个索引聚簇(index
cluster)创建的。
里面记录的是各个聚簇键。聚簇键和我们用得做多的索引键不一样,索引键指向的是一行数据,
聚簇键指向的是一个ORACLE
BLOCK。我们可以先通过以下命令创建一个索引簇。
create cluster
emp_dept_cluster
( deptno number(2) )
size 1024
/
size参数:
向聚簇中放数据之前,需要先对聚簇建立索引。可以现在就在聚簇中创建表,
但是由于我们想同时创建和填充表,而有数据之前必须有一个聚簇索引,所以我们先来 建立聚簇索引。
create index
emp_dept_cluster_idx
on cluster emp_dept_cluster
/
建表:
create table
dept
( deptno number(2) primary
key,
dname varchar2(14),
loc varchar2(13)
)
cluster emp_dept_cluster(deptno)
/
create table emp
(
empno
number primary key,
ename
varchar2(10),
job
varchar2(9),
mgr
number,
hiredate
date,
sal
number,
comm
number,
deptno number(2) constraint emp_fk references
dept(deptno)
) cluster emp_dept_cluster(deptno)
/
什么时候不应该使用聚簇?
1) 如果预料到聚簇中的表会大量修改:
必须知道,索引聚簇会对DML的性能产生某种负面影响(特别是INSERT语句)。管理聚簇中的数据需要做更多的工作。
2) 如果需要对聚簇中的表执行全表扫描:不只是必须对你的表中的数据执行全面扫描,
还必须对(可能的)多个表中的数据进行全面扫描。由于需要扫描更多的数据,
所以全表扫描耗时更久。
3) 如果你认为需要频繁地TRUNCATE和加载表:聚簇中的表不能截除。
这是显然的,因为聚簇在一个块上存储了多个表,必须删除聚簇表中的行。
因此,如果数据主要用于读(这并不表示“从来不写”;聚簇表完全可以修改),
而且要通过索引来读(可以是聚簇键索引,也可以是聚簇表上的其他索引),
另外 会频繁地把这些信息联结在一起,此时聚簇就很适合。
堆表(heap table)数据插入时时存储位置是随机的,主要是数据库内部块的空闲情况决定,获取数据是按照命中率计算,全表扫表时不见得先插入的数据先查到。
索引表(iot)数据存储是把表按照索引的方式存储的,数据是有序的,数据的位置是预先定好的,与插入的顺序没有关系。
索引表的查询效率逼堆表高(相当于查询索引的效率),插入数据的速度比堆表慢。
索引表适用场景:
适用于信息检索、空间和OLAP程序。
1、 代码查找表。
2、 经常通过主码访问的表。
3、 构建自己的索引结构。
4、 加强数据的共同定位,要数据按特定顺序物理存储。
5、
经常用between…and…对主码或唯一码进行查询。数据物理上分类查询。如一张订单表,按日期装载数据,想查单个客户不同时期的订货和统计情况。
http://blog.itpub.net/16628454/viewspace-607795/
基于堆表和索引组织表的实例分析
加载中,请稍候......