在索引 table 中创建分区

Create partition in an indexed table

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

我显然会进行间隔或范围分区,但发现间隔分区对索引 table 不起作用。所以请帮助我使用语法,以便 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 位

使用 autopartitiong 和 LOCAL(分区)索引创建 table。 local_partitioned_index 子句让您指定索引在相同的列上分区,具有与 table 相同的分区数和相同的分区边界。 Oracle 数据库在重新分区底层 table 时自动维护本地索引分区。

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;

The INTERVAL clause of the CREATE TABLE statement establishes interval partitioning for the table. You must specify at least one range partition using the PARTITION clause. The range partitioning key value determines the high value of the range partitions, which is called the transition point, and the database automatically creates interval partitions for data beyond that transition point. The lower boundary of every interval partition is the non-inclusive upper boundary of the previous range or interval partition.

For example, if you create an interval partitioned table with monthly intervals and the transition point at January 1, 2010, then the lower boundary for the January 2010 interval is January 1, 2010. The lower boundary for the July 2010 interval is July 1, 2010, regardless of whether the June 2010 partition was previously created. Note, however, that using a date where the high or low bound of the partition would be out of the range set for storage causes an error. For example, TO_DATE('9999-12-01', 'YYYY-MM-DD') causes the high bound to be 10000-01-01, which would not be storable if 10000 is out of the legal range.

一些关于 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;