Oracle11g在分区方面做了很大的提高,不但新增了4种复合分区类型,还增加了虚拟列分区、系统分区、INTERVAL分区等功能。
11g以前的分区表,需要指定一个或多个分区字段,并根据这个分区字段的值,按照一定的算法(RANGE、HASH和LIST)来决定一条记录属于那个分区。
从11g开始,Oracle允许用户不指定分区列,完全根据程序来控制数据存储在那个分区中。这就是11g提供的系统分区功能。
在以前,确定了分区列和分区方式,那么一条数据属于哪个分区也就被确定下来。而对于系统分区而言,分区是分区,数据是数据,二者没有对应的关系。数据可以被放在任意一个分区中,这不是由数据本身决定的,而是应用程序在插入时确定的。
SQL> CREATE TABLE T_SYSTEM
2 (ID NUMBER, NAME VARCHAR2(30))
3 PARTITION BY SYSTEM
4 (PARTITION P1, PARTITION P2, PARTITION P3, PARTITION P4);
表已创建。
SQL> INSERT INTO T_SYSTEM VALUES (1, 'ABC');
INSERT INTO T_SYSTEM VALUES (1, 'ABC')
*第 1 行出现错误:
ORA-14701: 对于按“系统”方法进行分区的表, 必须对 DML 使用分区扩展名或绑定变量
对于系统分区表,插入的时候必须指定分区:
SQL> INSERT INTO T_SYSTEM PARTITION (P1) VALUES (1, 'ABC');
已创建 1 行。
SQL> INSERT INTO T_SYSTEM PARTITION (P2) VALUES (1, 'ABC');
已创建 1 行。
SQL> SELECT ROWID, ID, NAME FROM T_SYSTEM;
ROWID ID NAME
------------------ ---------- ------------------------------
AAARcdAAFAAAB2nAAA 1 ABC
AAARceAAFAAAB2vAAA 1 ABC
SQL> SELECT ID, NAME,
2 (SELECT SUBOBJECT_NAME FROM USER_OBJECTS WHERE DATA_OBJECT_ID = DBMS_ROWID.ROWID_OBJECT(A.ROWID))
3 FROM T_SYSTEM A;
ID NAME (SELECTSUBOBJECT_NAMEFROMUSER_
---------- ------------------------------ ------------------------------
1 ABC P1
1 ABC P2
从上面可以看到,对于SYSTEM分区方式,完全相同的数据也可以插入到两个不同的分区中。数据和分区没有任何关系。
对于系统分区表可以使用绝大部分分区维护功能,除了ALTER TABLE SPLIT PARTITION功能。因为没有分区列,Oracle无法将分区中的数据分配到两个新的分区中。
同样的道理,采用了系统分区的分区表是不能通过CREATE TABLE AS SELECT方式创建的。
而且,由于没有分区列,因此无法创建唯一的LOCAL索引。
系统分区方式继承了分区带来的可用性和易维护性的好处,但是分区消除对于系统分区是无效的。由于不清楚数据存放在那个分区,因此对于系统分区中数据的查找需要在所有分区中进行。
系统分区要求INSERT语句必须包括分区描述语句,SELECT、UPDATE和DELETE语句则不需要。如果考虑到分区消除对系统分区无效,那么如果了解数据存储在哪个分区中,最好在DML的时候指定分区,这样可以提供查询的性能,避免全表扫描的产生。
阅读(367) | 评论(0) | 转发(0) |