Oracle:使用自动列表分区和范围子分区

时间:2019-05-16 07:26:06

标签: oracle oracle12c database-partitioning

我想使用一种分区方法将表分为二维:

  1. 第一个维度是键列表。该列表会随着时间的推移而增长,并且如果密钥列表将得到扩展,我并不需要DBA来添加分区。因此,我想使用自动列表分区

  2. 第二个维度是日期列的每日范围。

这是我的示例,给我一个 ORA-14179

CREATE TABLE PartitionedTable
( 
  id              number,
  PartitionKey    number,
  created         date
) 
PARTITION BY LIST (PartitionKey) AUTOMATIC
SUBPARTITION BY RANGE (created) INTERVAL (NUMTODSINTERVAL(1,'DAY'))
( PARTITION p_PartitionKey VALUES (1)
  ( SUBPARTITION p_created VALUES LESS THAN (TO_DATE('01-JAN-2000','dd-MON-yyyy'))
  )
);

我正在使用 Oracle Database 12c企业版12.2.0.1.0版-64位生产版本

如果插入新的键和新的日期,是否可以用最少的精力来创建二维分区表?

3 个答案:

答案 0 :(得分:2)

The problem is

  

子分区级别不支持间隔分区。

自动列表子分区同样适用-也不受支持。因此,您无法使用间隔自动分区来解决此问题。因此,无论您做什么,都将需要进行子分区维护以将值分开。

如果您的目标是减少(子)分区维护,那么使用间隔列表分区表可能会更好。带有列表值的默认分区。

您可以随时更改子分区模板。这定义了在添加新的顶级分区时数据库创建的子分区。

例如,这将创建一个间隔列表表:

create table partitionedtable ( 
  id              number,
  partitionkey    number,
  created         date
) 
partition by range (created) interval (numtodsinterval(1,'day'))
subpartition by list (partitionkey) 
subpartition template  (
  subpartition p1 values ( 1 ),
  subpartition pdef values ( default )
) ( 
  partition p2000 values less than ( date'2019-01-01' )
);

insert into partitionedtable values ( 1, 1, date'2019-01-02' );
insert into partitionedtable values ( 1, 2, date'2019-01-02' );

值2进入默认子分区。

您发现了这一点,并更新了模板以包括一个子分区:

alter table partitionedtable
  set subpartition template (
    subpartition p1 values ( 1 ),
    subpartition p2 values ( 2 ),
    subpartition pdef values ( default )  
  );

insert into partitionedtable values ( 1, 1, date'2019-01-03' );
insert into partitionedtable values ( 1, 2, date'2019-01-03' );

select partition_name, subpartition_name, high_value 
from   user_tab_subpartitions;

PARTITION_NAME    SUBPARTITION_NAME    HIGH_VALUE   
P2000             P2000_P1             1             
P2000             P2000_PDEF           default       
SYS_P772          SYS_SUBP771          default       
SYS_P772          SYS_SUBP770          1             
SYS_P776          SYS_SUBP773          1             
SYS_P776          SYS_SUBP774          2             
SYS_P776          SYS_SUBP775          default   

新分区(SYS_P776)的子分区值为2。现有分区未更改。如果要在此处将值2的行放在其自己的子分区中,则需要拆分SYS_P772。

假设已创建=>插入日期,这意味着您只需要在新分区键的第一次插入和更改模板的日期之间分割子分区。

对于自动范围分区,对于每个新的分区键,您需要管理新的日期子分区。

像这样翻转分区方案还有其他含义。因此,在继续操作之前,请检查这是否符合您进行分区的其他原因(查询性能,数据存档等)。

答案 1 :(得分:2)

子分区级别不支持间隔和列表自动分区。
也许最好没有子分区。 multiple keys也可以使用virtual columnsautomatic list partitioning。考虑以下演示:

create table parttab (
    id number, key number, created date, 
    partkey varchar (16) as (to_char (key, 'FM099999')||'-'||to_char (created, 'yyyymmdd')) virtual 
)
partition by list (partkey) automatic (partition pdefault values ('000000-19000101'))
;

insert into parttab (id, key, created) 
    select rownum id, trunc (rownum/5)+1 key, date'2019-01-01' + trunc (rownum/4)
    from xmlTable ('1 to 6')
; 

select partition_name, high_value, num_rows
from user_tab_partitions
where table_name = upper ('parttab') 
;

新创建的分区看起来像这样:

PARTITION_NAME   HIGH_VALUE           NUM_ROWS
---------------- ------------------ ----------
PDEFAULT         '000000-19000101'           0
SYS_P1588        '000001-20190101'           3
SYS_P1589        '000001-20190102'           1
SYS_P1590        '000002-20190102'           2

答案 2 :(得分:1)

对于所有感兴趣的人,我目前正在使用以下策略来满足我的所有要求:

CREATE TABLE PartitionedTable
( 
  id              number,
  PartitionKey    number,
  created         date,
  trunc_created date generated always as (trunc(created)) virtual
) 
PARTITION BY LIST (PartitionKey, trunc_created) AUTOMATIC
(  
  PARTITION PDEFAULT VALUES (1, to_date('01.01.2000', 'DD.MM.YYYY'))
);