Oracle本地分区索引

1 分区索引
分区索引与非分区索引相比,具有许多好处。使用分区索引的关键好处如下:
.性能方面的优势
.通过DML操作载入数据。
.通过DDL操作载入数据。
.用select语句查询数据。

.维护方面的好处
.重建索引。
.在分区一级把索引设置为不可用或不可见。

可以创建本地分区或全局分区的分区索引。本地分区索引只能存在于分区表,而全局分区的索引既可以在分区表创建,也可以在非分区表上创建。还可以在分区表上创建非分区索引。分区索引最常见的配置是在分区表上创建本地分区索引,只是因为这种配置的整体优势一般大于分区表上的全局分区索引和非分区索引。

注意:创建分区表上的非分区索引与创建非分区表上的非分区索引是相同的。

2 创建本地分区索引
最常见的分区索引类型是本地分区索引。本地分区索引只能在分区表上创建。顾名思义,“本地”是指索引条目和相应的数据之间有直接的关系。数据分区和索引分区之间存在一对一的关系。如果有某个按日期范围分区的表,今年每个月都有一个分区,那么对于2012年1月分区的所有数据,创建的每个索引在2012年1月分区都有相应的索引项。

2.1 最简单的形式
除LOCAL关键字外,最基本的创建本地分区索引的形式与创建非分区索引相同。

create table employees_part
(
EMPLOYEE_ID   NUMBER(6),
FIRST_NAME    VARCHAR2(20),
LAST_NAME     VARCHAR2(25),
EMAIL         VARCHAR2(25),
PHONE_NUMBER  VARCHAR2(20),
HIRE_DATE     DATE,
JOB_ID        VARCHAR2(10),
SALARY        NUMBER(8,2),
COMMISSION_PCT NUMBER(2,2),
MANAGER_ID     NUMBER(6),
DEPARTMENT_ID  NUMBER(4)
)
partition by range(hire_date)
(
   partition p01 values less than(to_date('2002-01-01','yyyy-mm-dd')),
   partition p02 values less than(to_date('2003-01-01','yyyy-mm-dd')),
   partition p03 values less than(to_date('2004-01-01','yyyy-mm-dd')),
   partition p04 values less than(to_date('2005-01-01','yyyy-mm-dd')),
   partition p05 values less than(to_date('2006-01-01','yyyy-mm-dd')),
   partition p06 values less than(to_date('2007-01-01','yyyy-mm-dd')),
   partition p07 values less than(to_date('2008-01-01','yyyy-mm-dd')),
   partition p08 values less than(to_date('2009-01-01','yyyy-mm-dd')),
   partition p09 values less than(to_date('2010-01-01','yyyy-mm-dd')),
   partition p10 values less than(to_date('2011-01-01','yyyy-mm-dd')),
   partition p11 values less than(to_date('2012-01-01','yyyy-mm-dd')),
   partition p12 values less than(to_date('2013-01-01','yyyy-mm-dd'))
);
/




SQL> create table employees_part
  2  (
  3  EMPLOYEE_ID   NUMBER(6),
  4  FIRST_NAME    VARCHAR2(20),
  5  LAST_NAME     VARCHAR2(25),
  6  EMAIL         VARCHAR2(25),
  7  PHONE_NUMBER  VARCHAR2(20),
  8  HIRE_DATE     DATE,
  9  JOB_ID        VARCHAR2(10),
 10  SALARY        NUMBER(8,2),
 11  COMMISSION_PCT NUMBER(2,2),
 12  MANAGER_ID     NUMBER(6),
 13  DEPARTMENT_ID  NUMBER(4)
 14  )
 15  partition by range(hire_date)
 16  (
 17     partition p01 values less than(to_date('2002-01-01','yyyy-mm-dd')),
 18     partition p02 values less than(to_date('2003-01-01','yyyy-mm-dd')),
 19     partition p03 values less than(to_date('2004-01-01','yyyy-mm-dd')),
 20     partition p04 values less than(to_date('2005-01-01','yyyy-mm-dd')),
 21     partition p05 values less than(to_date('2006-01-01','yyyy-mm-dd')),
 22     partition p06 values less than(to_date('2007-01-01','yyyy-mm-dd')),
 23     partition p07 values less than(to_date('2008-01-01','yyyy-mm-dd')),
 24     partition p08 values less than(to_date('2009-01-01','yyyy-mm-dd')),
 25     partition p09 values less than(to_date('2010-01-01','yyyy-mm-dd')),
 26     partition p10 values less than(to_date('2011-01-01','yyyy-mm-dd')),
 27     partition p11 values less than(to_date('2012-01-01','yyyy-mm-dd')),
 28     partition p12 values less than(to_date('2013-01-01','yyyy-mm-dd'))
 29  );
/
Table created.


SQL> insert into employees_part select * from employees;

107 rows created.

SQL> commit;

Commit complete.


SQL> create index employees_part_i1 on employees_part(hire_date) local;

Index created.

对于这个例子,Oracle创建的分区名称将与数据分区的名称相同。此外,所有分区都将在USERS表空间内创建。

根据应用程序的需求,可能需要指定各个分区的具体信息,比如下列内容:
.分区名称
.表空间名称
.存储参数

2.2 分区级的需求
如果有特定的分区级的需求,就需要在create index ddl内指定每个分区的信息。例如:

SQL> create index employees_part_i2 on employees_part(hire_date) local
  2  (
  3  partition pi01,
  4  partition pi02,
  5  partition pi03,
  6  partition pi04,
  7  partition pi05,
  8  partition pi06,
  9  partition pi07,
 10  partition pi08,
 11  partition pi09,
 12  partition pi10,
 13  partition pi11,
 14  partition pi12
 15  );

Index created.

在这个例子中,对分区名称进行了修改,在表分区名中间插入一个i来表示索引分区。为了让索引具有与表不同的分区名称,必须在create indexddl中指定每个分区的名称。还可以为每个分区指定不同的表空间,因为它代表了一年的数据。把每年的数据放在自己的表空间内,就可以把往年数据的表空间设置为只读。这有助于提高查询速度和备份速度,因为你不需要在数据库的每个备份中都备份只读表空间。

再次强调,要创建本地分区索引,必须是在分区表上创建。否则,就会出现以下错误提示信息:

SQL> create index employees_i1 on employees(hire_date) tablespace users local;
create index employees_i1 on employees(hire_date) tablespace users local
                             *
ERROR at line 1:
ORA-14016: underlying table of a LOCAL partitioned index must be partitioned

2.3 前缀和非前缀选项
可以把本地分区索引创建为前缀或非前缀的。在创建本地分区的前缀索引时,这意味着表的分区列在索引的前导端。如果分区列不在索引的前导端,就被当作非前缘索引。在Oracle的早期版本中,本地前缀索引与非前缀索引相比,在性能上有一些优势。在Oracle后来的版本中,包括版本11gR2,建立本地前缀索引的优势已经减弱。不过,如果你的数据库环境是OLTP系统,本地前缀索引比非前缀索引更有利于提高查询性能,因为为了检索某个查询所需的数据,优化器需要扫描的索引分区可能会较少。

在创建本地分区的唯一索引时,索引必须包括分区列,否则就会出现以下错误提示信息:

SQL> create unique index employees_part_pk on employees_part(employee_id) local;
create unique index employees_part_pk on employees_part(employee_id) local
                                         *
ERROR at line 1:
ORA-14039: partitioning columns must form a subset of key columns of a UNIQUE index

在唯一索引的定义中添加分区列(在本例中是hire_date)后,就可以在employees_part表上创建唯一索引了。

SQL> create unique index employees_part_pk on employees_part(employee_id,hire_date) local;

Index created.

发表评论

电子邮件地址不会被公开。