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

Mar*_*ser 5 database oracle oracle11g

案件

  1. 该系统dispositives基本上由形成id, type, name.
  2. 我可以有N个dispositives.
  3. 我有一张桌子来储存log所有的东西dispositives.这是系统中最大的表.(现在计算100英里的记录)
  4. log表有:id_dispositive, date, status.

问题

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

今天,我有这样dispositivestype:

TYPE     COUNT
---------------
1         78956  
2         125161
3         13213
4         6112
5         25426
6         12314
7         1241
8         622
Run Code Online (Sandbox Code Playgroud)

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

我的"解决方案"

我正在考虑分区这​​张log桌子.这是问题:

  1. 值得吗?
  2. 我应该按类型分区吗?
  3. 我应该按DATE类型和子分区进行分区吗?
  4. 我可以通过编程方式进行吗?

由于这种类型是动态的,用户可以删除/插入新的.

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

根据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'))
));
Run Code Online (Sandbox Code Playgroud)

我得到了:

ORA-14004: PARTITION keyword not found.
Run Code Online (Sandbox Code Playgroud)

Fra*_*rra 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'))
);
Run Code Online (Sandbox Code Playgroud)

对于类型列也可以进行同样的操作。更多信息: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'))
);
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您无法创建自动子分区,如果要添加新类型,您必须运行 alter table 语句。这里有更多信息;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'))
);
Run Code Online (Sandbox Code Playgroud)

如果您尝试插入:

insert into prova_log values (1,1,TO_DATE('10/10/2016','dd/mm/yyyy'),1);
Run Code Online (Sandbox Code Playgroud)

您将在桌子上看到 2 个分区。

现在我已经测试过了!