oracle表分区和索引分区

㈠ 分区表技术概述

  **⑴ Range 分区**

  **① 例子**

     create table t
     (...列定义...)
     partition by range (week_num)
     (partition p1 values less than (4)tablespace data0,
       partition p2 values less than (5)tablespace data1,
       ....
      );

  **② 适用场景**

     Range 分区一般比较适合按时间周期进行数据的存储

  **③ 优点**

     用户知道具体数据落在哪个分区
     因此、通过分区可以有效实施各种大批量的数据管理操作
     比如、删除指定时间段的历史数据管理、对指定分区进行备份恢复或导入导出

**  ④ 缺点**

     ● 分区的数据可能不均匀
     ● Range分区与记录值相关、实施难度和可维护性相对较差

  **⑵ List分区**

  **① 例子 **

     create table t
     (...列定义...)
     partition by list(city)
     (partition p1 values ('北京') tablespace data0,
      partition p2 values ('上海') tablespace data1,
      ....
     );

  Range 和 List 的区别在于、前者是连续、而后者是离散
  因此、在优缺点及适用场景方面、大抵相去无几
  这里不赘述了

  **⑶ HASH 分区**

  **① 例子**

     create table t
     (...列的定义..)
     partition by hash (customer_no)
     partition 8 store in 
     (data0,data1);

     友情提醒哦:Oracle建议HASH分区数一般是2的幂,数据会随机地(尽可能均匀)分布在各个分区,我们无法控制一行数据分布在哪个分区上

  **② 适用场景**

     HASH分区适合于静态数据
     何谓静态数据?
     指此类数据一般永远存储在数据库中、不需要进行历史数据迁移
     例如:用户资料表、账户信息等
     而这类信息的访问大部分通过用户ID或者账号进行
     如果按这些字段进行HASH分区、并建立本地前缀分区索引、访问效率相当高哦

  **③ 优点**

     ● 数据均匀分布
     ● 实施非常简单

  **④ 缺点**
     用户不知道某条记录具体会落在哪个分区
     因此、HASH分区不适合大批量数据管理操作
     例如、历史数据清理、大批量数据导入导出等

  **⑷ 组合分区**

  Oracle组合分区某种程度上讲是一种把优点集中的表现
  例如、大多数情况下、第一维按时间字段进行分区、
  这样在分区级适合于进行大批量数据管理操作
  第二维的HASH或List可进一步提高访问性能或者降低实施难度

  11g之前只有:Range-HASH 或 Range-List

㈡ 分区索引技术概述

  生产环境中、有时我们会遇到:
  已经做了分区表了、怎么性能没有提高啊?甚至更慢啊?
  其原因之一或者是没有合理甚至根本没有设计分区索引

  先总体认识一下表和索引在分区上的关系:

  ![image](http://upload-images.jianshu.io/upload_images/2657562-c555728264428662.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

⑴ 本地前缀分区索引

  假设分区表为一个交易流水表t、且按交易日期date进行Range分区
  如果欲创建date字段上的索引、我们可以:
  create index idx_t on t (date) local;
  idx_t 就叫做本地前缀索引
  所谓本地、指索引的分区方法与对应表的分区方法一样。每个表分区都会有一个索引分区,并且这个索引分区仅对这个表分区的数据进行索引。
  所谓前缀、指分区字段是索引字段的前缀 **优势**
  ● 提高查询性能
  ● 当某个分区进行drop 或 merge后、Oracle自动对所对应的索引分区进行相同的操作、
     整个本地前缀分区索引依然有效、无须rebuild
     这样大大保证了表的可用性

  **⑵ 本地非前缀分区索引**

  假设我们需要在t表的area字段建立分区索引、我们可以:
  create index idx_t_area on t (area) local;
  idx_t_area就叫做本地非前缀分区索引

  非前缀要按照索引扫描所有的分区、性能可能更低
  不过、它能够保证按索引访问的可用性

适用场景:
如果历史数据整理非常频繁、而且不能承受全局分区索引重建的长时间带来的索引不可用
同时、日常交易性能尚能接受、则建议设计为本地非前缀分区索引

注意:本地分区索引不能保证唯一性(除非分区键是约束的一部分)

  **⑶ 全局分区索引**

  假设我们需要在t表的area字段建立分区索引、我们可以:
  create index idx_t_g_area on t(area)
  global partition by range (area)
  (partition p1 less than ...);
  所谓全局、是指该索引的分区与表的分区无关
  10g以后、Oracle提供2种全局分区索引:
  ● Global Range Partition Index 
  ● Global HASH Partition Index 

缺点:
主要体现在数据的高可用性方面
当DROP分区后、全局分区索引则全部INVALID、除非REBULID
但数据量越大、重建索引的时间越长
一般来讲,如果需要将数据按照某个值逻辑聚集,多采用范围分区。如基于时间数据的按“年”、“月”等分区就是很典型的例子。在许多情况下,范围分区都能利用到分区消除特性( = >= <= between…and 等筛选条件下)。

如果在表里无法找到一个合适的属性来按这个属性完成范围分区,但你又想享受分区带来的性能与可用性的提升,则可以考虑使用散列分区。(适合使用 = IN 等筛选条件)

如果数据中有一列或有一组离散值,且按这一列进行分区很有意义,则这样的数据就很适合采用列表分区。

如果某些数据逻辑上可以进行范围分区,但是得到的范围分区还是太大,不能有效管理,则可以考虑使用组合分区(范围分区+hash 或范围分区+列表分区)。
create table products_table
(
id number(2),
name varchar2(50),
sale_date date
)
partition by range(sale_date)
interval (numtoyminterval(1,'month'))
(
partition p_month_1 values less than (to_date('2016-01-01','yyyy-mm-dd'))
)

如图,取 products_table 中的 sale_date 列作为分区键创建按月自增分区;

所有销售时间在 ‘2016-01-01’之前的记录都会被放入 p_month_1 分区;

销售时间在‘2016-01-01’之后的记录在插入时Oracle会自动创建记录所属月的分区;

比如当有销售时间分别为 2016年1月20日 与 2016年2月20日 的两条记录插入时,Oracle会分别创建一个上限值为 ‘2016-01-31’的分区和一个上限值为‘2016-02-29’的分区来存储这两条记录
https://www.cnblogs.com/Dreamer-1/p/6132776.html

你可能感兴趣的:(oracle表分区和索引分区)