Oracle数据库中,有两种类型的分区索引,全局索引和本地索引,其中本地索引又可以分为本地前缀索引和本地非前缀索引。下面就分别看看每种类型的索引各自的特点。

全局索引以整个表的数据为对象建立索引,索引分区中的索引条目既可能是基于相同的键值但是来自不同的分区,也可能是多个不同键值的组合。

全局索引既允许索引分区的键值和表分区键值相同,也可以不相同。全局索引和表之间没有直接的联系,这一点和本地索引不同。

SQL> create table orders (
     order_no      number,
     part_no       varchar2(40),
     ord_date      date
     )
     partition by range (ord_date)
      (partition Q1 values less than (TO_DATE('01-APR-1999','DD-MON-YYYY')),
       partition Q2 values less than (TO_DATE('01-JUL-1999','DD-MON-YYYY')),
       partition Q3 values less than (TO_DATE('01-OCT-1999','DD-MON-YYYY')),
       partition Q4 values less than (TO_DATE('01-JAN-2000','DD-MON-YYYY'))
      )
     ;

Table created.

SQL> create index orders_global_1_idx
     on orders(ord_date)
      global partition by range (ord_date)
       (partition GLOBAL1 values less than (TO_DATE('01-APR-1999','DD-MON-YYYY')),
        partition GLOBAL2 values less than (TO_DATE('01-JUL-1999','DD-MON-YYYY')),
        partition GLOBAL3 values less than (TO_DATE('01-OCT-1999','DD-MON-YYYY')),
        partition GLOBAL4 values less than (MAXVALUE)
       )
     ;

Index created.

SQL> create index orders_global_2_idx
     on orders(part_no)
      global partition by range (part_no)
       (partition IND1 values less than (555555),
        partition IND2 values less than (MAXVALUE)
       )
     ;

Index created.

从上面的语句可以看出,全局索引和表没有直接的关联,必须显式的指定maxvalue值。假如表中新加了分区,不会在全局索引中自动增加新的分区,必须手工添加相应的分区。

SQL> alter table orders add partition Q5 values less than (TO_DATE('01-APR-2000','DD-MON-YYYY'));

Table altered.

SQL> select TABLE_NAME, PARTITION_NAME from dba_tab_partitions where table_name='ORDERS';

TABLE_NAME                     PARTITION_NAME
------------------------------ ------------------------------
ORDERS                         Q1
ORDERS                         Q2
ORDERS                         Q3
ORDERS                         Q4
ORDERS                         Q5

SQL> select INDEX_NAME, PARTITION_NAME from dba_ind_partitions where index_name=upper('orders_global_1_idx');

INDEX_NAME                     PARTITION_NAME
------------------------------ ------------------------------
ORDERS_GLOBAL_1_IDX            GLOBAL1
ORDERS_GLOBAL_1_IDX            GLOBAL2
ORDERS_GLOBAL_1_IDX            GLOBAL3
ORDERS_GLOBAL_1_IDX            GLOBAL4

使用全局索引,索引键值必须和分区键值相同,这就是所谓的前缀索引。Oracle不支持非前缀的全局分区索引,如果需要建立非前缀分区索引,索引必须建成本地索引。

SQL> create index orders_global_2_idx
  2  on orders(part_no)
  3   global partition by range (order_no)
  4    (partition IND1 values less than (555555),
  5     partition IND2 values less than (MAXVALUE)
  6    )
  7  ;
 global partition by range (order_no)
                                    *
ERROR at line 3:
ORA-14038: GLOBAL partitioned index must be prefixed

接下来再来看看本地分区。

本地索引的分区和其对应的表分区数量相等,因此每个表分区都对应着相应的索引分区。使用本地索引,不需要指定分区范围因为索引对于表而言是本地的,当本地索引创建时,Oracle会自动为表中的每个分区创建独立的索引分区。

创建本地索引不必显式的指定maxvalue值,因为为表新添加表分区时,会自动添加相应的索引分区。

create index orders_local_1_idx
on orders(ord_date)
 local
  (partition LOCAL1,
   partition LOCAL2,
   partition LOCAL3,
   partition LOCAL4
  )
;

Index created.

SQL> select INDEX_NAME, PARTITION_NAME from dba_ind_partitions where index_name=upper('orders_local_1_idx');

INDEX_NAME                     PARTITION_NAME
------------------------------ ------------------------------
ORDERS_LOCAL_1_IDX             LOCAL1
ORDERS_LOCAL_1_IDX             LOCAL2
ORDERS_LOCAL_1_IDX             LOCAL3
ORDERS_LOCAL_1_IDX             LOCAL4

SQL> alter table orders add partition Q5 values less than (TO_DATE('01-APR-2000','DD-MON-YYYY'));

Table altered.

SQL> select INDEX_NAME, PARTITION_NAME from dba_ind_partitions where index_name=upper('orders_local_1_idx');

INDEX_NAME                     PARTITION_NAME
------------------------------ ------------------------------
ORDERS_LOCAL_1_IDX             LOCAL1
ORDERS_LOCAL_1_IDX             LOCAL2
ORDERS_LOCAL_1_IDX             LOCAL3
ORDERS_LOCAL_1_IDX             LOCAL4
ORDERS_LOCAL_1_IDX             Q5

这里系统已经自动以和表分区相同的名字自动创建了一个索引分区。同理,删除表分区时相对应的索引分区也自动被删除。

本地索引和全局索引还有一个显著的差别,就是上面提到的,本地索引可以创建成本地非前缀型,而全局索引只能是前缀型。

SQL> create index orders_local_2_idx
     on orders(part_no)
      local
       (partition LOCAL1,
        partition LOCAL2,
        partition LOCAL3,
        partition LOCAL4)
     ;

Index created.

SQL> select INDEX_NAME, PARTITION_NAME, HIGH_VALUE from dba_ind_partitions
     where index_name=upper('orders_local_2_idx');

INDEX_NAME                     PARTITION_NAME                 HIGH_VALUE
------------------------------ ------------------------------ ---------------------------------------------------------
ORDERS_LOCAL_2_IDX             LOCAL1                         TO_DATE(' 1999-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 
                                                              'NLS_CALENDAR=GREGORIA'
ORDERS_LOCAL_2_IDX             LOCAL2                         TO_DATE(' 1999-07-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 
                                                              'NLS_CALENDAR=GREGORIA'
ORDERS_LOCAL_2_IDX             LOCAL3                         TO_DATE(' 1999-10-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
                                                              'NLS_CALENDAR=GREGORIA'
ORDERS_LOCAL_2_IDX             LOCAL4                         TO_DATE(' 2000-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
                                                              'NLS_CALENDAR=GREGORIA'

从上面的输出可以看出,虽然索引的键值是part_no,但索引分区的键值仍然和表的分区键值相同,即ord_date,也即是所谓的非前缀型索引。

最后,再引用一个例子说明前缀索引和非前缀索引的应用。

假设有一个使用DATE列分区的大表。我们经常使用一个VARCHAR2列(VCOL)进行查询,但这个列并不是表的分区键值。

有两种可能的方法来访问VCOL列的数据,一是建立基于VCOL列的本地非前缀索引,

|                                         |
             -------                                   -------
            |       |         (10 more                |        |
Values:     A..     Z..   partitions here)            A..      Z..

另一种是建立基于VCOL列的全局索引,

|                                         |
              -------                                   -------
             |       |         (10 more                |        |
Values:      A..     D..   partitions here)            T..      Z..

可以看出,如果能够保证VCOL列值的唯一性,全局索引将会是最好的选择。如果VCOL列值不唯一,就需要在本地非前缀索引的并行查询和全局索引顺序查询以及高昂的维护代价之间做出选择。

ORACLE 全局索引和本地索引的更多相关文章

  1. Oracle非分区索引,全局分区索引和本地分区索引。

    1.如果按照索引是否分区作为划分依据,Oracle 的索引类型可以分为非分区索引,全局分区索引和本地分区索引. 2.创建演示实例 --创建非分区表create table test_partition ...

  2. Oracle 分区表中本地索引和全局索引的适用场景

    背景 分区表创建好了之后,如果需要最大化分区表的性能就需要结合索引的使用,分区表有两种索引:本地索引和全局索引.既然存在着两种的索引类型,相信存在即合理.既然存在就会有存在的原因,也就是在特定的场景中 ...

  3. Oracle 学习总结 - 表和索引的性能优化

    表的性能 表的性能取决于创建表之前所应用的数据库特性,数据库->表空间->表,创建数据库时确保为每个用户创建一个默认的永久表空间和临时表空间并使用本地管理,创建表空间设为本地管理并且自动段 ...

  4. Oracle 分区表的索引、分区索引

    对于分区表,可以建立不分区索引.也就是说表分区,但是索引不分区.以下着重介绍分区表的分区索引. 索引与表一样,也可以分区.索引分为两类:locally partition index(局部分区索引). ...

  5. Oracle—表、约束、索引、表空间、分区、序列、统计信息

    表.约束.索引.表空间.分区.序列.统计信息 一.表及其操作 1.创建表 create table 表名 ( 字段名1 字段类型 默认值 是否为空 , 字段名2 字段类型 默认值 是否为空, 字段名3 ...

  6. 全局索引与分区索引对于SQL性能影响的比较

    KingbaseES 提供了对于分区表 global index 的支持.global index 不仅提供了对于唯一索引功能的改进(无需包含分区键),而且在性能上相比非global index (l ...

  7. Oracle索引梳理系列(七)- Oracle唯一索引、普通索引及约束的关系

    版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...

  8. oracle唯一索引与普通索引的区别和联系以及using index用法

    oracle唯一索引与普通索引的区别和联系 区别:唯一索引unique index和一般索引normal index最大的差异是在索引列上增加一层唯一约束.添加唯一索引的数据列可以为空,但是只要尊在数 ...

  9. Oracle中NULL值与索引

    NULL值是关系数据库系统布尔型(true,false,unknown)中比较特殊类型的一种值,通常称为UNKNOWN或空值,即是未知的,不确定的.由于NULL存在着无数的可能,因此NULL值也不等于 ...

随机推荐

  1. C && C++ 内存分配示意图

    <Unix环境系统高级编程>中的C语言内存分布示意图 1.C内存分布 BSS段: 用来存放程序中未初始化的全局变量.BSS是英文Block Started by Symbol的简称.BSS ...

  2. 能"干掉"苹果的中国"黑客"

    他是全球发现苹果漏洞最多的人,他曾穷的住在小黑屋,他经常接到国家安全部门的电话,他差点堵住周鸿祎的路,他是谁? 无名英雄 我们最终还是没有见到吴石本人,即便他的生意合伙人刘盛(化名)已经应承了帮我们牵 ...

  3. html rowspan colspan代码示例

    <html> <body> <table border="1"> <tr> <td rowspan="4" ...

  4. Asp.net 身份验证

    Forms 验证方式对基于用户的验证授权提供了很好的支持,可以通过一个登录页面验证用户的身份,将此用户的身份发回到客户端的Cookie,之后此用户再访问这个 web应用就会连同这个身份Cookie一起 ...

  5. hdu 1376 Octal Fractions

    刚开始做这题时,用的是0.75[8]=(7/8+5/64)[10]这个,但是总是WA…………无语了…… 后来看别人的解题报告,知道了另外一个就是0.75[8]=((5/8+7)/8)[10],从低位向 ...

  6. http://www.oschina.net/translate/elasticsearch-getting-started?cmp

    http://www.oschina.net/translate/elasticsearch-getting-started?cmp

  7. lintcode 中等题:partition array 数组划分

    题目 数组划分 给出一个整数数组nums和一个整数k.划分数组(即移动数组nums中的元素),使得: 所有小于k的元素移到左边 所有大于等于k的元素移到右边 返回数组划分的位置,即数组中第一个位置i, ...

  8. lintcode : 二叉树的最小深度

    题目: 二叉树的最小深度 给定一个二叉树,找出其最小深度. 二叉树的最小深度为根节点到最近叶子节点的距离. 样例 给出一棵如下的二叉树: 1 /     \ 2       3 /    \ 4    ...

  9. java四种数组排序

    数组的四种排序 1.快速排序法Arrays.sort(); 用法1.sort(byte[] a)      对指定的 byte 型数组按数字升序进行排序. sort(byte[] a, int fro ...

  10. LR_问题_在导入wsdl时出现parsing error

    问题描述:使用LR录制webservice协议的脚本,在导入wsdl时出现parsing error,详见图 问题解决:在导入wsdl时输入的地址错误,只指定了地址的虚拟目录名称,未指定方法名称,应该 ...