分区

分区概述

在 Oracle 数据库中,分区使您能够将非常大的表和索引分解为更小且更易于管理的部分,称为分区每个分区都是一个独立的对象,具有自己的名称和可选的存储特性。

举例说明分区,假设人力资源经理有一个包含员工文件夹的大盒子。每个文件夹都列出了员工雇用日期。查询通常针对特定月份雇用的员工。满足此类请求的一种方法是创建员工雇用日期索引,指定分散在整个盒子中的文件夹的位置。相比之下,分区策略使用许多较小的盒子,每个盒子都包含在给定月份雇用的员工的文件夹。

使用较小的盒子有几个优点。当被要求检索 6 月份雇用的员工的文件夹时,HR 经理可以检索 6 月份的框。此外,如果任何小盒子暂时损坏,其他小盒子仍然可用。移动办公室也变得更容易,因为经理可以移动几个小箱子,而不是移动一个沉重的箱子。

从应用程序的角度来看,只存在一个模式对象。SQL 语句无需修改即可访问分区表。分区对于许多不同类型的数据库应用程序很有用,尤其是那些管理大量数据的应用程序。好处包括:

  • 提高可用性

分区不可用并不意味着对象不可用。查询优化器会自动从查询计划中删除未引用的分区,因此当分区不可用时查询不会受到影响。

  • 更轻松地管理模式对象

分区对象具有可以集中或单独管理的部分。DDL语句可以操作分区而不是整个表或索引。因此,您可以分解资源密集型任务,例如重建索引或表。例如,您可以一次移动一个表分区。如果出现问题,那么只有分区移动必须重做,而不是表移动。此外,删除分区可避免执行大量DELETE语句。

  • 减少OLTP系统 中共享资源的争用

在某些 OLTP 系统中,分区可以减少对共享资源的争用。例如,DML 分布在许多段而不是一个段上。

  • 增强数据仓库中的查询性能

数据仓库中,分区可以加快即席查询的处理速度。例如,包含一百万行的销售表可以按季度进行分区。

分区特性

表或索引的每个分区必须具有相同的逻辑属性,例如列名、数据类型和约束。

例如,表中的所有分区共享相同的列和约束定义。但是,每个分区都可以有单独的物理属性,例如它所属的表空间。

分区键

分区键是一组一个或多个列,它确定分区表中的每一行应该进入的分区每一行都明确地分配给一个分区。

sales表中,您可以将time_id列指定为范围分区的键。数据库根据此列中的日期是否在指定范围内为分区分配行。Oracle 数据库使用分区键自动将插入、更新和删除操作定向到适当的分区。

分区策略

Oracle Partitioning 提供了多种分区策略来控制数据库如何将数据放入分区中。基本策略是范围、列表和哈希分区。

单级分区仅使用一种数据分布方法,例如仅列表分区或仅范围分区。复合分区中,通过一种数据分布方法对表进行分区,然后使用第二种数据分布方法将每个分区进一步划分为子分区。例如,您可以使用列表分区channel_id和范围子分区time_id

示例

此分区示例假定您要sales使用以下行填充分区表:

  PROD_ID    CUST_ID TIME_ID   CHANNEL_ID   PROMO_ID QUANTITY_SOLD AMOUNT_SOLD
---------- ---------- --------- ---------- ---------- ------------- -----------
      116      11393 05-JUN-99          2        999             1       12.18
       40     100530 30-NOV-98          9         33             1       44.99
      118        133 06-JUN-01          2        999             1       17.12
      133       9450 01-DEC-00          2        999             1       31.28
       36       4523 27-JAN-99          3        999             1       53.89
      125       9417 04-FEB-98          3        999             1       16.86
       30        170 23-FEB-01          2        999             1         8.8
       24      11899 26-JUN-99          4        999             1       43.04
       35       2606 17-FEB-00          3        999             1       54.94
       45       9491 28-AUG-98          4        350             1       47.45 

范围分区

范围分区中,数据库根据分区键的值范围将行映射到分区。范围分区是最常见的分区类型,通常与日期一起使用。

假设您time_range_sales使用以下 SQL 语句创建分区表,并将time_id列作为分区键:

CREATE TABLE time_range_sales
   ( prod_id        NUMBER(6)
   , cust_id        NUMBER
   , time_id        DATE
   , channel_id     CHAR(1)
   , promo_id       NUMBER(6)
   , quantity_sold  NUMBER(3)
   , amount_sold    NUMBER(10,2)
   )
PARTITION BY RANGE (time_id)
 (PARTITION SALES_1998 VALUES LESS THAN (TO_DATE('01-JAN-1999','DD-MON-YYYY')),
  PARTITION SALES_1999 VALUES LESS THAN (TO_DATE('01-JAN-2000','DD-MON-YYYY')),
  PARTITION SALES_2000 VALUES LESS THAN (TO_DATE('01-JAN-2001','DD-MON-YYYY')),
  PARTITION SALES_2001 VALUES LESS THAN (MAXVALUE)
 ); 

然后,使用示例中的行加载time_range_sales。代码显示了四个分区中的行分布。数据库根据partition BY RANGE子句中指定的规则,根据time_id值为每行选择分区。范围分区键值确定指定分区的非包容性上限。

间隔分区

区间分区是范围分区的扩展。

如果插入的数据超出现有范围分区,Oracle 数据库会自动创建指定间隔的分区。例如,您可以创建一个销售历史表,将每个月的数据存储在单独的分区中。

间隔分区使您能够避免显式创建范围分区。您可以对几乎每个范围分区的表使用间隔分区,并为新分区使用固定间隔。除非您创建具有不同间隔的范围分区,或者除非您始终设置特定的分区属性,否则请考虑使用间隔分区。

按间隔分区时,必须至少指定一个范围分区。范围分区键值决定范围分区的高值,称为转换点。数据库会自动为值超出转换点的数据创建间隔分区。每个区间分区的下边界是前一个范围或区间分区的包含上边界。因此,在示例4-2中,值01-JAN-2011位于分区p2中。

数据库为过渡点以外的数据创建间隔分区。间隔分区通过指示数据库创建指定范围或间隔的分区来扩展范围分区。当插入到表中的数据超过所有现有范围分区时,数据库会自动创建分区。在示例4-2中,p3分区包含分区键time_id值大于或等于2013年1月1日的行。

Example 4-2 Interval Partitioning

假设您创建了一个具有四个宽度不同的分区的销售表。您指定在2013年1月1日的过渡点以上,数据库应每隔一个月创建分区。分区p3的上限表示过渡点。分区p3和它下面的所有分区都在range部分,而它上面的所有分区则属于interval部分。

CREATE TABLE interval_sales
    ( prod_id        NUMBER(6)
    , cust_id        NUMBER
    , time_id        DATE
    , channel_id     CHAR(1)
    , promo_id       NUMBER(6)
    , quantity_sold  NUMBER(3)
    , amount_sold    NUMBER(10,2)
    ) 
  PARTITION BY RANGE (time_id) 
  INTERVAL(NUMTOYMINTERVAL(1, 'MONTH'))
    ( PARTITION p0 VALUES LESS THAN (TO_DATE('1-1-2010', 'DD-MM-YYYY'))
    , PARTITION p1 VALUES LESS THAN (TO_DATE('1-1-2011', 'DD-MM-YYYY'))
    , PARTITION p2 VALUES LESS THAN (TO_DATE('1-7-2012', 'DD-MM-YYYY'))
    , PARTITION p3 VALUES LESS THAN (TO_DATE('1-1-2013', 'DD-MM-YYYY')) );

You insert a sale made on date October 10, 2014:

SQL> INSERT INTO interval_sales VALUES (39,7602,'10-OCT-14',9,null,1,11.79);

1 row created.

USER_TAB_PARTIONS查询显示,数据库为10月10日的销售创建了一个新分区,因为销售日期晚于过渡点:

SQL> COL PNAME FORMAT a9
SQL> COL HIGH_VALUE FORMAT a40
SQL> SELECT PARTITION_NAME AS PNAME, HIGH_VALUE 
  2  FROM USER_TAB_PARTITIONS WHERE TABLE_NAME = 'INTERVAL_SALES';

PNAME     HIGH_VALUE
--------- ----------------------------------------
P0        TO_DATE(' 2007-01-01 00:00:00', 'SYYYY-M
          M-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
P1        TO_DATE(' 2008-01-01 00:00:00', 'SYYYY-M
          M-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
P2        TO_DATE(' 2009-07-01 00:00:00', 'SYYYY-M
          M-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
P3        TO_DATE(' 2010-01-01 00:00:00', 'SYYYY-M
          M-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P1598 TO_DATE(' 2014-11-01 00:00:00', 'SYYYY-M
          M-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA

待续。。。。。。

 

posted @ 2022-09-21 22:11  wongchaofan  阅读(203)  评论(0编辑  收藏  举报