
4.6 创建索引组织表(IOT)
索引组织表是Oracle提供的一种特殊类型的表,它将数据和索引存储在一起,按照索引的结构来组织和存储表中的数据。索引组织表的存储结构不是堆组织表,我们知道堆中数据的存储是无序的,而索引组织表中的数据是按照某个主键排序后存储的,然后再以B树的组织结构存储在数据段中。
索引组织表对于经常使用主键字段来实现查询的事务非常高效,索引组织表的主键约束不能被删除、延期和禁止。使用IOT表,其索引与数据合二为一的特殊结构会带来很多好处,如IOT节约了磁盘空间的占用,大幅度降低了I/O,从而减少了访问缓冲区缓存,少读数据就可以不必多次读缓冲区,因为缓冲区缓存获取都需要缓冲区缓存的多个闩。
IOT适用的场合有:
● 完全由主键组成的表。这样的表如果采用堆组织表,则表本身完全是多余的开销,因为所有的数据同样也保存在索引里,此时,堆表是没用的。
● 如果你只会通过一个主键来访问一个表,这个表就非常适合实现为IOT。
● 数据以某种特定的顺序物理存储,IOT就是一种合适的结构。如果经常在一个主键或唯一键上使用between查询,也是如此。如果数据有序地物理存储,就能提升这些查询的性能。
4.6.1 IOT表的结构
我们使用最简单的语句创建一个索引组织表,然后通过其创建元语句的查询,看看Oracle的索引组织表的创建到底需要什么参数,然后我们分别解释这些参数的含义以及使用场合。
创建一个最简单的索引组织表。
SQL> create table tiot 2 (x int primary key, 3 y number, 4 z varchar2(20)) 5 organization index; 表已创建。
下面我们提取表定义元数据。
SQL> select DBMS_METADATA.GET_DDL('TABLE','TIOT') FROM DUAL;
DBMS_METADATA.GET_DDL('TABLE','TIOT')
------------------------------------------------------------------------------
CREATE TABLE "SYS"."TIOT"
( "X" NUMBER(*,0),
"Y" NUMBER,
"Z" VARCHAR2(20),
PRIMARY KEY ("X") ENABLE
) ORGANIZATION INDEX NOCOMPRESS PCTFREE 10 INITRANS 2 MAXTRANS 255 LOGGING
STORAGE(INITIAL 45534 NEXT 1048574 MINEXTENTS 1 MAXEXTENTS 2147483445
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "SYSTEM"
PCTTHRESHOLD 50
注意
创建IOT时,必须要设定主键,否则报错,索引组织表实际上将所有数据都放入了索引中。
我们通过获得表TIOT的定义元数据获得了Oracle创建一个简单的IOT表时的内部操作。需要注意与普通HEAP表不同的几个参数,如ORGANIZATION INDEX、NOCOMPRESS、PCTTHRESHOLD等。其实IOT表还有两个属性需要注意,分别是OVERFLOW和INCLUDING。
下面我们解释索引组织表属性。
● ORGANIZATION INDEX:说明这是个索引组织表。
● OVERFLOW:允许我们创建一个新段,如果IOT的行记录太大,则可以存储到这个新段上去。那么什么时候使用这个新段呢。就需要考虑一下PCTTHRESHOLD和INCLUDING两个参数。
● INCLUDING:行中从第一列直到INCLUDING所指定的列的所有列数据都存储在索引块上,其余列存储在溢出段上。
● PCTTHRESHOLD:如果行中的数据量超过了数据块大小的百分比,行中其余的数据就要放入溢出段了。
● COMPRESS(键压缩):和普通的索引一样,索引组织表也可以使用COMPRESS子句进行键压缩以消除重复值。具体的操作是,在organization index之后加上COMPRESS,n子句。n的意义在于,指定压缩的列数,默认为无穷大。
4.6.2 创建IOT表
创建IOT表的关键是如何使用IOT的参数,下面我们创建IOT表的PCTTHRESHOLD值为10,列Y(包含该列)的数据溢出到OVERFLOW参数指定的表空间USERS,违反PCTTHRESHOLD规则的行记录也会溢出到表空间USERS。如下所示,创建满足该条件的IOT表IOT_TEST。
SQL> create table iot_test 2 (x int, 3 y number, 4 z varchar2(20), 5 constraint iot_test_pk primary key(x) 6 ) 7 organization index 8 pctthreshold 10 9 including y 10 overflow tablespace users; 表已创建。
通过设置合理的属性值,我们创建了一个IOT表,该表的主键是X,从第二列(包含第二列)开始的所有列数据都存储到溢出段中,而对于第一列的数据只要不违反PCTTHRESHOLD的值就存储在索引块上,而一旦违反了这个规则就存储到溢出段中。