我应该分区/分区我的桌子吗?

时间:2016-07-22 14:47:01

标签: database oracle oracle11g

案例

  1. 系统有dispositives,基本上由id, type, name
  2. 组成
  3. 我可能有N dispositives
  4. 我有一张表来存储log的所有dispositives。这是系统中最大的表。 (现在计算100英里记录)
  5. log表格包含:id_dispositive, date, status
  6. 问题

    显然这个巨大的数据导致了性能问题。我必须存储至少两个月的日志值..

    今天我有dispositives type

    TYPE     COUNT
    ---------------
    1         78956  
    2         125161
    3         13213
    4         6112
    5         25426
    6         12314
    7         1241
    8         622
    

    我还有一些业务逻辑来提供这个log表。无论如何,这是我的想法:

    我的“解决方案”

    我在想这个log表的分区。以下是问题:

    1. 值得吗?
    2. 我应该按类型进行分区吗?
    3. 我应该按DATE类型和子分区进行分区吗?
    4. 我可以通过编程方式进行吗?
    5. 由于这种类型是动态的,用户可以删除/插入新类型。

      因此,如果删除某些类型,我必须删除该类型的所有日志。 好像他们插入了某种类型,我必须注册(存储)该类型的所有日志。

      根据Francesco Serra的回答编辑

      我正在尝试创建这样的表:

      create table log(
             id_dispositive    number,
             type       number,
             date_verification    date,
             status  number
      )
      partition by range (date_verification) 
      subpartition by list (type)  
      subpartition TEMPLATE (
          SUBPARTITION type1 VALUES (1),
          SUBPARTITION type2 VALUES (2),
          SUBPARTITION type3 VALUES (3),
          SUBPARTITION type4 VALUES (4)
      )(                           
      interval (numtoyminterval(1,'MONTH'))(
         partition p0816 values less than (to_date('01/09/2016','dd/mm/yyyy'))
      ));
      

      我得到了:

      ORA-14004: PARTITION keyword not found.
      

1 个答案:

答案 0 :(得分:1)

您可以尝试这种方式:使用INTERVAL告诉oracle创建自动分区。您必须定义列(数字或日期)和间隔(在我的示例中为1个月)。 Oracle会在相同的时间间隔内将所有行放入同一个分区(在本例中为同一个月)。如果分区不存在则将被创建。

create table log(
       id_dispositive    number,
       date    date,
       status  number,
       type    number
)
partition by range (date)                              
interval (numtoyminterval(1,'MONTH'))(
   partition p0701 values less than (to_date('2007-02-01','yyyy-mm-dd'))
);

同样可以使用类型列来完成。更多信息:http://www.oracle.com/technetwork/articles/sql/11g-partitioning-084209.html

每个分区都可以使用TEMPLATE键进行子分区。

create table log(
       id_dispositive    number,
       date    date,
       status  number,
       type    number
)
partition by range (date) interval (numtoyminterval(1,'MONTH'))
subpartition by list (type)  
subpartition TEMPLATE (
    SUBPARTITION types1 VALUES (1, 2) TABLESPACE tbs_1,
    SUBPARTITION types2 VALUES (3, 4) TABLESPACE tbs_1
)                          
(
   partition p0701 values less than (to_date('2007-02-01','yyyy-mm-dd'))
);

在这种情况下,您无法创建自动子分区,如果要添加新类型,则必须运行alter table statment。这里有更多信息; https://docs.oracle.com/cd/B28359_01/server.111/b32024/part_admin.htm#i1006655

在您的示例中:

create table prova_log(
       id_dispositive    number,
       type       number,
       date_verification    date,
       status  number
)
partition by range (date_verification) interval (numtoyminterval(1,'MONTH'))
subpartition by list (type)  
subpartition TEMPLATE (
    SUBPARTITION type1 VALUES (1),
    SUBPARTITION type2 VALUES (2),
    SUBPARTITION type3 VALUES (3),
    SUBPARTITION type4 VALUES (4)
)                          
(
   partition p0816 values less than (to_date('01/09/2016','dd/mm/yyyy'))
);

如果您尝试插入:

insert into prova_log values (1,1,TO_DATE('10/10/2016','dd/mm/yyyy'),1);

你会在桌子上看到2个分区。

现在我已经测试了它!