索引组织表(IOT)不仅可以存储数据,还可以存储为表建立的索引。索引组织表的数据是根据主键排序后的顺序进行排列的,这样就提高了访问的速度。但是这是由牺牲插入和更新性能为代价的(每次写入和更新后都要重新进行重新排序)。
JEL@JEL >create table iot_addr (empno references emp(empno) on delete cascade,addr varchar2(10),primary key (empno,addr)) organization index;
JEL@JEL >select dbms_metadata.get_ddl('TABLE','IOT_ADDR') FROM DUAL;
DBMS_METADATA.GET_DDL('TABLE','IOT_ADDR')
--------------------------------------------------------------------------------
CREATE TABLE "JEL"."IOT_ADDR"
( "EMPNO" NUMBER,
"ADDR" VARCHAR2(10),
PRIMARY KEY ("EMPNO", "ADDR") ENABLE,
FOREIGN KEY ("EMPNO")
REFERENCES "JEL"."EMP" ("EMPNO") ON DELETE CASCADE ENABLE
) ORGANIZATION INDEX NOCOMPRESS PCTFREE 10 INITRANS 2 MAXTRANS 255 LOGGING
STORAGE(INITIAL 2097152 NEXT 2097152 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "JEL"
DBMS_METADATA.GET_DDL('TABLE','IOT_ADDR')
--------------------------------------------------------------------------------
PCTTHRESHOLD 50
注意两点:
● 创建IOT时,必须要设定主键,否则报错。
● 索引组织表实际上将所有数据都放入了索引中。
NOCOMPRESS--oracle把每个值分别存储在各个索引条目中。如果对象的主键在A、B和C列上,A、B和C的每一次出现都会物理的存储。反过来是compress N,这里N是一个整数,表示压缩的列数。这样可以避免重复值,这样在A的值重复出现时,将不再物理的存储他们。这不会降低并发性,可能显著的减少I/O,并允许更多的数据在缓冲区中缓存,原因是每个块中能有更多的数据。测试如下:
JEL@JEL >create table iot (owner,object_type,object_name,constraint iot_pk primary key(owner,object_type,object_name)) organization index nocompress as select distinct owner,object_type,object_name from all_objects;
Table created.
JEL@JEL >analyze index iot_pk validate structure;
Index analyzed.
JEL@JEL >select lf_blks,br_blks,used_space,opt_cmpr_count,opt_cmpr_pctsave from index_stats;
LF_BLKS BR_BLKS USED_SPACE OPT_CMPR_COUNT OPT_CMPR_PCTSAVE
---------- ---------- ---------- -------------- ----------------
44 1 310167 2 34
JEL@JEL >alter table iot move compress 1;
Table altered.
JEL@JEL >analyze index iot_pk validate structure;
Index analyzed.
JEL@JEL >select lf_blks,br_blks,used_space,opt_cmpr_count,opt_cmpr_pctsave from index_stats;
LF_BLKS BR_BLKS USED_SPACE OPT_CMPR_COUNT OPT_CMPR_PCTSAVE
---------- ---------- ---------- -------------- ----------------
37 1 265135 2 23
JEL@JEL >alter table iot move compress 2;
Table altered.
JEL@JEL >analyze index iot_pk validate structure;
Index analyzed.
JEL@JEL >select lf_blks,br_blks,used_space,opt_cmpr_count,opt_cmpr_pctsave from index_stats;
LF_BLKS BR_BLKS USED_SPACE OPT_CMPR_COUNT OPT_CMPR_PCTSAVE
---------- ---------- ---------- -------------- ----------------
29 1 203386 2 0
overflow--因为所有数据都放入索引,所以当表的数据量很大时,会降低索引组织表的查询性能。此时设置溢出段将主键和溢出数据分开来存储以提高效率。如果IOT的行数据变得太大,就可以溢出到另外的段。构成主键的列不能溢出,他们必须直接放到叶子块上。
pctthreshold,行中的数据量超过块的这个百分比时,行中余下的列就存储在溢出段中
including,行中第一列直到including子句所指定的列(包含这一列)的所有列都存储到索引块上,余下的列存储在溢出段中。
当行中某字段的数据量无法确定时使用PCTTHRESHOLD。
若所有行均超出PCTTHRESHOLD规定大小,则考虑使用INCLUDING。
IOT 就是类似一个全是索引的表,表中的所有字段都放在索引上,所以就等于是约定了数据存放的时候是按照严格规定的,在数据插入以前其实就已经确定了其位置,所以不管插入的先后顺序,它在那个物理上的那个位置与插入的先后顺序无关。这样在进行查询的时候就可以少访问很多blocks,但是插入的时候,速度就比普通的表要慢一些。
适用于信息检索、空间和OLAP程序。
使用IOT的好处:
1、由于索引项和数据存储在一起,所以无论是基于主键的等值查询还是范围查询都能大大节省磁盘访问时间。
2、为了能够更快地访问那些频繁访问的列,可以使用溢出存储选项将那些访问不频繁的列放在B树叶结点数据块之外的溢出堆空间中。这样一来便可以得到更小的B树,以及包含更多行的叶结点
3、和堆组织表和索引不同,主键不需要被存储两次。
4、ROWID伪列是基于主键值的逻辑rowid,而不是物理rowid,即使表被重新组织过,造成了基表行的迁移,二级索引仍然可用,不需要重建。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/29337971/viewspace-1062714/
,如需转载,请注明出处,否则将追究法律责任。