首页 > Linux操作系统 > Linux操作系统 > 分区表和分区索引(Final)
非分区表可以使用分区或非分区索引,分区表也可以使用分区或非分区索引。
分区键 --
分区键(partition key)是决定数据行属于哪个分区的一组数据列。Oracle 在执行插入,更新,及删除
操作时能根据分区键自动地选择分区。分区表内的每个数据行都能且只能分配到一个分区中(partition) 。
分区键的特点如下:
由 1 至 16 个数据列顺序构成
不能包含 LEVEL,ROWID,或 MLSLABEL 虚列(pseudocolumn),也不能包含类型为 ROWID 的列
不能包含可为空(NULLable)的列
分区表 --
一个表最多可由 1024K-1 个分区构成。任何表都能够被分区,除非其中含有数据类型为 LONG 或 LONG RAW
的列。注意,含 CLOB 或 BLOB 类型列的表可以被分区。为了减少磁盘及内存空间(尤其是数据库缓存)的
使用,用户可以采用压缩的形式存储表及分区表。这有助于提高只读操作的可伸缩性(scaleup)。表压缩还
能提升查询的执行速度 ,但会造成一些额外的 CPU 开销。
分区方法 --
范围分区: 依据用户创建分区时设定的分区键值(partition key value)范围将数据映射到不同分区。范围
分区是较常用的分区方式,通常针对日期数据使用。
列表分区: 用户在各分区的定义中指定一个分区键离散值的列表,从而实现列表分区
哈希分区: 通过一个哈希函数(hash function)控制数据行与分区间的映射关系, 用户可以采用哈希
分区(hash partitioning)将不适于采用范围分区(range partitioning)或列表分区(list partitioning)
的数据进行分区。哈希分区的语法(syntax)简单且易于实现。在以下情况时哈希分区比范围分区更适用:
用户无法事先确定一个分区可能存储的数据量
各范围分区的容量可能相差很大,或很难通过人工进行平衡
采用范围分区可能导致数据不正常的集中
应用系统对并行 DML(parallel DML),分区剪除(partition pruning),及基于分区的关联
(partition-wise joins)等与性能有关的分区特性要求较高
分割(splitting),移除(dropping ),及融合(merging)等操作不适用于哈希分区。但对哈希分区
可以进行添加(add)及接合(coalesce)操作。
CREATE TABLE sales_hash(
salesman_id NUMBER(5),
salesman_name VARCHAR2(30),
sales_amount NUMBER(10),
week_no NUMBER(2))
PARTITION BY HASH(salesman_id)
PARTITIONS 4
STORE IN (ts1, ts2, ts3, ts4);
上述语句创建了依据 salesman_id 字段进行哈希分区(hash partitioning)的分区表 sales_hash。此表使用
的表空间分别为 ts1,ts2,ts3,及 ts4。上述语句表明,将数据以循环(round-robin)的方式存储到语句中
指定的各个表空间中。
复合分区 : 复合分区(composite partitioning)首先根据范围(range)进行分区,再使用哈希或列表
方式创建子分区。复合范围-哈希分区既能够发挥范围分区的可管理性优势,也能够发挥哈希分区的数据分
布(data placement),条带化(striping),及并行化(parallelism)优势。复合范围-列表分区能够发
挥范围分区的可管理性优势,也能利用列表分区的显示控制能力 .
Oracle 支持范围-哈希(range-hash)复合分区及范围-列表(range-list)复合分区
与范围分区(range partitioning)及哈希分区(hash partitioning)有所区别,列表分区不支持分
区键中包含多列。如果一个表采用列表(list)分区方式,那么分区键只能由此表的一个数据列构成。
分区索引 --
表能按range,hash,list分区及组合分区,表分区后,其上的索引和普通表上的索引有所不同,
oracle对于分区表上的索引分为2类,即局部索引和全局索引,下面分别对这2种索引的特点和局限
性做个总结。
局部索引local index,也叫本地索引 --
1. 局部索引一定是分区索引,分区键等同于表的分区键,分区数等同于表的分区数,一句话,局部索引的
分区机制和表的分区机制一样。
2. 如果局部索引的索引列以分区键开头,则称为前缀局部索引。
3. 如果局部索引的列不是以分区键开头,或者不包含分区键列,则称为非前缀索引。前缀与非前缀的区别
在于是否索引的前导列是分区键。
4. 如果分区索引只有一个字段,那它就没有前缀与非前缀的概念,只有组合的分区索引才有前缀与非前缀的概念.
5. 前缀和非前缀索引都可以支持索引分区消除(定义见后面),前提是查询的条件中包含索引分区键。
6. 局部索引只支持分区内的唯一性,无法支持表上的唯一性,因此如果要用局部索引去给表做唯一性约
束,则约束中必须要包括分区键列。
7. 局部分区索引是对单个分区的,每个分区索引只指向一个表分区,全局索引则不然,一个分区索引能
指向n个表分区,同时,一个表分区,也可能指向n个索引分区,对分区表中的某个分区做truncate或者move,
shrink等,可能会影响到n个全局索引分区,正因为这点,局部分区索引具有更高的可用性。
8. 位图(bitmap)索引只能为局部分区索引。
9. 局部索引多应用于数据仓库环境中(因为大多数时候在没有表分区键的local index会发生全索引分区扫描)。
用前缀索引能够帮助oracle在解析SQL的时候知道去哪个分区找数据。如果使用非前缀索引,则oracle可
能会对所有的分区进行扫描。
全局索引global index --
1. 全局索引的分区键和分区数和表的分区键和分区数可能都不相同,表和全局索引的分区机制不一样。
比如表中的数据分区是6个,索引分区可以是2个,3个,4个,5个,6个或更多 。
2. 全局索引可以分区,也可以是不分区索引,全局索引必须是前缀索引,即全局索引的索引列必须是
以索引分区键作为其前几列。比如:
create index gidx_range_exampel_id on range_example(id)
GLOBAL partition by range(id)
(
part_01 values less than(1000),
part_02 values less than(MAXVALUE)
);
create index gidx_range_exampel_id on range_example(id,sn)
GLOBAL partition by range(id)
(
part_01 values less than(1000),
part_02 values less than(MAXVALUE)
);
而不能出现这样的全局分区索引:
create index gidx_range_exampel_id on range_example(sn)
GLOBAL partition by range(id)
(
part_01 values less than(1000),
part_02 values less than(MAXVALUE)
);
3. 全局分区索引的索引条目可能指向若干个分区,因此,对于全局分区索引,即使只截断一个分区中
的数据,都需要rebulid若干个分区甚至是整个索引。
4. 全局索引多应用于OLTP系统中。
5. 全局分区索引只按range或者hash分区,hash分区是10G以后才支持。
6. oracle9i以后对分区表做move或者truncate的时可以用update global indexes语句来同步更新全局
分区索引,用消耗一定资源来换取高度的可用性。
7. 表用a列作分区,索引用b做局部分区索引,若where条件中用b来查询,那么oracle会扫描所有的表
和索引的分区,成本会比分区更高,此时可以考虑用b做全局分区索引, 不过这样做后在表中的分区
删除后,索引的维护成本相对高一些,需要重建或rebuild .
分区索引字典
DBA_PART_INDEXES 分区索引的概要统计信息,可以得知每个表上有哪些分区索引,分区索引的类型
(local/global,)
DBA_ind_partitions每个分区索引的分区级统计信息
DBA_indexesminusdba_part_indexes,可以得到每个表上有哪些非分区索引
索引重建
Alter index idx_name rebuild partition index_partition_name [online nologging]
需要对每个分区索引做rebuild,重建的时候可以选择online(不会锁定表),或者nologging建立
索引的时候不生成日志,加快速度。
Alter index rebuild idx_name [online nologging]
对非分区索引,只能整个index重建。
-- 什么叫做分区消除(剪除)
Oracle 数据库服务器能够识别出对象的分区(partition)及子分区(subpartition)。进而根据分区情况优
化 SQL 语句,标识出需要存取的分区及子分区,不会存取不必要的分区及子分区(即剪除(prune))。也可
以这样理解,分区剪除(partition pruning)就是在查询中跳过不必存取的分区及子分区。
对于每个 SQL 语句,Oracle 能够根据用户设定的查询条件(selection criteria),避免访问不需要的分
区及子分区。例如,一个查询只需要三月份的销售数据,就不必获取其余十一个月的数据。这种智能剪除技
术(intelligent pruning)能够显著地减少数据访问量,从而大幅提升查询性能。
如果优化器(optimizer)在剪除过程中确定某些分区或子分区中的全部数据与某些查询条件相对应,她在评估
语句时将从谓项列表(predicate list)(即WHERE 子句)中移除这些查询条件,从而提升语句的执行性能。
但是,如果用户在 SQL 语句中的分区键上使用了函数(TO_DATE 除外),优化器将无法对相关分区进行分区
剪除。与此类似的是,如果用户在 SQL 语句中的索引键上使用了函数(函数索引(function-based index)
除外),优化器也将无法使用相关的索引。
如果表及其上的索引依据不同列进行分区,在查询器优化查询时即使不能对表分区进行剪除,也可以对索
引分区进行剪除。用户创建分区索引后,就能有效减少SQL 语句所需存取的数据量,从而提升在大数据量表
上执行操作的性能。
对于相等(equality),范围(range),LIKE,及 IN-列表(list)等谓词可以考虑通过范围分区
(range partitioning)或列表分区(list partitioning)来实现分区剪除;对于相等,IN-列表等谓词
还可以通过范哈希分区(hash partitioning)来实现分区剪除。
基于分区的关联 --
基于分区的关联(partition-wise join)是指,当两个分区表相互关联的列分别对应各自的分区
键时而采取的关联优化措施。采用了基于分区的关联后,关联操作可以被分解为多个子操作,并可
采用串行(sequentially)或并行(parallel)的执行方式。也可以从另一个角度看待基于分区的
关联所做的优化工作,即此功能通过将数据处理均匀分布给多个子进程,减少了并行关联过程中各个
子进程间的数据交换量。
在 OLTP 系统中使用分区索引 --
以下是在 OLTP 系统中使用分区索引的一些指导建议:
全局分区索引(global partitioned index)及唯一本地分区索引(unique local partitioned index)
与非唯一本地分区索引(nonunique local partitioned index)相比能够提供更好的性能。前两者能够
最小化需要被检索的索引分区。
在对表的分区或子分区进行维护时,本地分区索引具备更高的可用性。
全局哈希分区索引(global hash-partitioned index)在索引值单调增长的情况下能够 均匀分布索
引数据,从而提升系统性能。索引值单调增长指新索引数据只会插入到索引的右边界外。
在数据仓库及 DSS 系统中使用分区索引 --
以下是在数据仓库系统及 DSS 系统中使用分区索引的一些指导建议:
应尽可能地使用本地分区索引(local partitioned index),因为此类索引在数据加载过程中及进
行分区维护操作时更易管理(data load)
本地分区索引有助于提升系统性能,因为对一个范围内的索引键进行查询时,可以并行地扫描多个分区。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/35489/viewspace-668041/ ,如需转载,请注明出处,否则将追究法律责任。