在索引表中创建分区

时间:2016-02-25 06:58:06

标签: oracle indexing partitioning

我有一张表可以保存12小时的数据。每隔5分钟,它会不断删除超过12小时的数据并添加新数据。它有近15-20万行。我想按小时创建分区,并在列(time_stamp)上索引表,以使行更快地获取。

我显然会进行间隔或范围分区,但发现间隔分区不适用于索引表。因此,请帮助我使用语法,以便oracle创建12个分区,并在添加新的time_stamp数据(自前12个小时后)后自动添加新分区。我已经有一个程序来删除我将使用的最旧的分区,以便始终有12小时的数据。

我正在陈述下面的列。

CustomerId,ApplicationId,Time_Stamp,Service

我试图想出这个,但不知道它将如何创建新分区

 CREATE TABLE local_table 
(customerid  VARCHAR2(30), 
applicationid VARCHAR2(30), 
time_stamp  TIMESTAMP, 
service   VARCHAR2(30))
PARTITION BY RANGE(time_stamp) 
(
PARTITION t1 VALUES LESS THAN(TO_TIMESTAMP('2015-02-25 00:00:00.0','YYYY-MM-DD HH24:MI:SS.ff')),
PARTITION t2 VALUES LESS THAN(TO_TIMESTAMP('2015-02-25 01:00:00.0','YYYY-MM-DD HH24:MI:SS.ff')),
PARTITION t3 VALUES LESS THAN(TO_TIMESTAMP('2015-02-25 02:00:00.0','YYYY-MM-DD HH24:MI:SS.ff')),
PARTITION t4 VALUES LESS THAN(TO_TIMESTAMP('2015-02-25 03:00:00.0','YYYY-MM- DD HH24:MI:SS.ff')),
PARTITION t5 VALUES LESS THAN(TO_TIMESTAMP('2015-02-25 04:00:00.0','YYYY-MM-DD HH24:MI:SS.ff')),
PARTITION t6 VALUES LESS THAN(TO_TIMESTAMP('2015-02-25 05:00:00.0','YYYY-MM-DD HH24:MI:SS.ff')),
PARTITION t7 VALUES LESS THAN(TO_TIMESTAMP('2015-02-25 06:00:00.0','YYYY-MM-DD HH24:MI:SS.ff')),
PARTITION t8 VALUES LESS THAN(TO_TIMESTAMP('2015-02-25 07:00:00.0','YYYY-MM-DD HH24:MI:SS.ff')),
PARTITION t9 VALUES LESS THAN(TO_TIMESTAMP('2015-02-25 08:00:00.0','YYYY-MM-DD HH24:MI:SS.ff')),
PARTITION t10 VALUES LESS THAN(TO_TIMESTAMP('2015-02-25 09:00:00.0','YYYY-MM-DD HH24:MI:SS.ff')),
PARTITION t11 VALUES LESS THAN(TO_TIMESTAMP('2015-02-25 10:00:00.0','YYYY-MM-DD HH24:MI:SS.ff')),
PARTITION t12 VALUES LESS THAN(TO_TIMESTAMP('2015-02-25 11:00:00.0','YYYY-MM-DD HH24:MI:SS.ff'))
); 

create index index_time_stamp on local_table(TIME_STAMP);

我使用的是 - Oracle数据库11g企业版11.2.0.4.0版 - 64位

1 个答案:

答案 0 :(得分:0)

使用autopartitiong和LOCAL(分区)索引创建表。 local_partitioned_index子句允许您指定索引在相同的列上进行分区,具有与表相同的分区数和相同的分区范围。当数据库重新分区时,Oracle数据库会自动维护本地索引分区。

CREATE TABLE local_table 
  (customerid    VARCHAR2(30), 
   applicationid VARCHAR2(30), 
   time_stamp    TIMESTAMP, 
   service       VARCHAR2(30))
   PARTITION BY RANGE(time_stamp) 
   INTERVAL(NUMTODSINTERVAL(1, 'HOUR'))
   (PARTITION t1 VALUES LESS THAN(TO_TIMESTAMP('2015-02-25 00:00:00.0','YYYY-MM-DD HH24:MI:SS.ff'))
  ); 

CREATE INDEX index_time_stamp on local_table(TIME_STAMP) LOCAL;

SELECT *
  FROM user_tab_partitions;

INSERT INTO local_table VALUES('1', 'a', sysdate, 'b');

SELECT *
  FROM user_tab_partitions;

INSERT INTO local_table VALUES('2', 'c', sysdate + 1/1440, 'd');

SELECT *
  FROM user_tab_partitions;

INSERT INTO local_table VALUES('3', 'e', sysdate + 1/24, 'f');

SELECT *
  FROM user_tab_partitions;
  

CREATE TABLE语句的INTERVAL子句建立间隔   为表分区。您必须至少指定一个范围   使用PARTITION子句进行分区。范围分区键值   确定范围分区的高值,称为   转换点,数据库自动创建间隔   超出该转换点的数据分区。下边界   每个区间分区是非包含的上边界   先前的范围或间隔分区。

     

例如,如果使用monthly创建间隔分区表   区间和转折点在2010年1月1日,然后是较低的   2010年1月间隔的边界是2010年1月1日。较低的   2010年7月间隔的边界是2010年7月1日,无论如何   是否先前创建了2010年6月的分区。但请注意,   使用分区的上限或下限的日期   超出为存储设置的范围会导致错误。例如,   TO_DATE('9999-12-01','YYYY-MM-DD')导致上限   10000-01-01,如果10000不合法,将无法存储   范围。

关于DROP PARTITION的第二个问题的一些快速 DRAFT 。在取消注释ALTER TABLE之前检查并调试。您可以创建调度程序作业,以便每小时运行一段代码。

DECLARE
  l_pt_cnt   NUMBER;
  l_pt_name  VARCHAR2(100);
  l_minrowid ROWID;
  l_mindate  TIMESTAMP;
BEGIN
  -- get partition count
  SELECT count(*)
    INTO l_pt_cnt
    FROM user_tab_partitions
  WHERE table_name = 'LOCAL_TABLE';
  IF l_pt_cnt > 12 THEN
    SELECT min(time_stamp)
      INTO l_mindate
      FROM LOCAL_TABLE;
    -- get ROWID with min date
    SELECT min(rowid)
      INTO l_minrowid
      FROM LOCAL_TABLE
     WHERE time_stamp = l_mindate;
    -- get name of partition with row with min date
  SELECT subobject_name
    INTO l_pt_name
    FROM LOCAL_TABLE 
         JOIN user_objects 
           ON dbms_rowid.rowid_object(LOCAL_TABLE.rowid) = user_objects.object_id
   WHERE LOCAL_TABLE.rowid = l_minrowid;
   DBMS_OUTPUT.put_line('ALTER TABLE LOCAL_TABLE DROP PARTITION ' || l_pt_name );
   --EXECUTE IMMEDIATE 'ALTER TABLE LOCAL_TABLE DROP PARTITION ' || l_pt_name; 
  END IF;
END;