加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Oracle索引分区介绍

发布时间:2020-12-12 16:14:45 所属栏目:百科 来源:网络整理
导读:一. 概述 和表分区一样,索引也可以进行分区。oracle中对索引进行分区有两种方式: 每一个索引分区对应一个表分区,而且只索引该表分区。也就是有多少个表分区就有多少个索引分区。称之为局部分区索引。 索引按照区间分区(或者散列分区),一个索引可以指向

一. 概述

和表分区一样,索引也可以进行分区。oracle中对索引进行分区有两种方式:

  1. 每一个索引分区对应一个表分区,而且只索引该表分区。也就是有多少个表分区就有多少个索引分区。称之为局部分区索引。
  2. 索引按照区间分区(或者散列分区),一个索引可以指向任何表分区的数据。索引分区个数与表分区个数没有关系,称之为全局分区索引。

二. 局部索引

oracle中有两类局部索引:局部前缀索引和局部非前缀索引。看例子:

CREATE TABLE partitioned_table ( a int,b int,data char(20) ) PARTITION BY RANGE (a) ( PARTITION part_1 VALUES LESS THAN(2) tablespace p1,PARTITION part_2 VALUES LESS THAN(3) tablespace p2 )

如上语句创建了一个表,分成了2个区。a小于2的放在part_1区,a大于2小于3的放在part_2区。接着我们创建两个局部索引:

--局部前缀索引(索引的第一列为分区键)
create index local_prefixed on partitioned_table (a,b) local;   
--局部非前缀索引(索引的第一列非分区键,比如(b,a))
create index local_nonprefixed on partitioned_table (b) local;

往表里面插入一些数据:

insert into partitioned_table select mod(rownum-1,2)+1,rownum,'x' from all_objects;

将表空间p2离线,也就是part_2分区变成不可用:

alter tablespace p2 offline;

执行如下查询:

select * from partitioned_table where a = 1 and b = 1;

能够执行成功,使用的局部前缀索引,只查询了part_1分区。

执行第二个查询:

select * from partitioned_table where b = 1;

执行失败,使用的局部非前缀索引,其实这里与使用哪一种类型的局部索引木有关系,b=1的数据不能确定都在part_1区,故part_2分区也需要查找,由于part_2分区已经不可用,故查询失败。
将局部前缀索引删除,继续查询如下:

drop index local_prefixed;   
select * from partitioned_table where a = 1 and b = 1;

执行成功,这个时候只能使用局部非前缀索引,也只会扫描part_1分区,因为表分区已经定义了a小于2的值放在part_1分区。
因此,扫描哪些表分区,不扫描哪些表分区与使用什么类型的局部索引没有关系,只与表分区机制相关。
那么,什么情况使用局部前缀索引,什么情况使用局部非前缀索引呢?这个主要看你主要进行什么样的查询。比如:你主要会进行如下查询:select ... from partitioned_table where a = :a and b = :b; 那么在(a,b)列上建立一个局部前缀索引很合适。如果除开上面那个查询很频繁,下面这个查询也很频繁:select ... from partitioned_table where b = :b;那么在(b,a)上建立一个非前缀索引很合适。

三. 全局索引

与局部索引不同,全局索引只有一类,前缀全局索引。也就是全局索引的索引键应该从索引的分区键开始,无论用什么属性对索引分区,这些属性必须是索引键的前几列。比如:

CREATE TABLE partitioned ( timestamp date,id int ) PARTITION BY RANGE (timestamp) ( PARTITION part_1 VALUES LESS THAN ( to_date('01-jan-2000','dd-mon-yyyy') ),PARTITION part_2 VALUES LESS THAN ( to_date('01-jan-2001','dd-mon-yyyy') ) ) 

创建分区表,以timestamp列分区,接着运行如下SQL语句建立一个全局索引

create index partitioned_index on partitioned(id) GLOBAL partition by range(id) ( partition part_1 values less than(1000),partition part_2 values less than (MAXVALUE))

这个全局索引的索引键是id,索引的分区键是id。如果索引键指定为(timestamp,id)就会报错。 那么什么情况下使用局部索引,什么情况使用全局索引。这还是要看你需要查找什么样的数据。假如一个客户信息表,是按照客户的注册时间(regist_time)进行表分区的。如果我们要查找注册时间从date1到date2中姓王的所有客户信息,这个时候适合在客户名称(name)上建立一个局部索引。因为我们很可能只要查找一个表分区或者几个表分区,而不是所有的表分区都要扫描。但是,如果我们要查找的是某某地区姓王的客户信息。这个明显要扫描所有表分区,那么要建立一个全局索引在地区字段和姓名字段上。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读