如何创建为单个分区创建索引

设想有一个分区表,上面建了一个local index,如果只是想在最近的分区上使用索引,而老的分区上不需要创建索引,这样的功能只有在12c中提供,而此时就可以使用这个unusable特性,先创建local索引并将其状态置为unusable,然后将需要使用的索引分区进行rebuild,从而实现了针对单个分区创建索引的目的。

SQL> CREATE TABLE INV_HISTORY 
  2                        (inv_no NUMBER(10), inv_date DATE, inv_amt NUMBER(10,2))
  3    partition by range (inv_date) interval(numtoyminterval(1,'month')) 
  4                       (partition p0 values less than (to_date('01-01-2005','dd-mm-yyyy')), 
  5                        partition p1 values less than (to_date('01-01-2006','dd-mm-yyyy'))
  6                                      );

Table created.

SQL> insert into inv_history select rownum,to_date('2005-01-01','yyyy-mm-dd'),1000 from dual connect by level<=200000;

200000 rows created.

SQL> /

200000 rows created.

SQL> insert into inv_history select rownum,to_date('2004-01-01','yyyy-mm-dd'),1000 from dual connect by level<=200000;

200000 rows created.

SQL> /

200000 rows created.

SQL> commit;

Commit complete.

SQL> select count(*) from INV_HISTORY partition(p0);

  COUNT(*)
----------
    400000

SQL> select count(*) from INV_HISTORY partition(p1);

  COUNT(*)
----------
    400000

SQL> select segment_name,segment_type,partition_name,bytes/1024/1024 from user_segments;

SEGMENT_NAME                   SEGMENT_TYPE       PARTITION_NAME                 BYTES/1024/1024
------------------------------ ------------------ ------------------------------ ---------------
INV_HISTORY                    TABLE PARTITION    P0                                          10
INV_HISTORY                    TABLE PARTITION    P1                                          11

--创建索引并设置为unusable
SQL> CREATE INDEX inv_no_ix ON INV_HISTORY(inv_no) LOCAL unusable;

Index created.

--查看segment情况,发现unusable的索引没有创建segment
SQL> select segment_name,segment_type,partition_name,bytes/1024/1024 from user_segments;

SEGMENT_NAME                   SEGMENT_TYPE       PARTITION_NAME                 BYTES/1024/1024
------------------------------ ------------------ ------------------------------ ---------------
INV_HISTORY                    TABLE PARTITION    P0                                          10
INV_HISTORY                    TABLE PARTITION    P1                                          11

--此时可以对一个索引进行rebuild,rebuild之后该索引将变为usable状态
SQL> alter index INV_NO_IX  rebuild partition p1;

Index altered.

SQL> select segment_name,segment_type,partition_name,bytes/1024/1024 from user_segments;

SEGMENT_NAME                   SEGMENT_TYPE       PARTITION_NAME                 BYTES/1024/1024
------------------------------ ------------------ ------------------------------ ---------------
INV_HISTORY                    TABLE PARTITION    P0                                          10
INV_HISTORY                    TABLE PARTITION    P1                                          11
INV_NO_IX                      INDEX PARTITION    P1                                           8

SQL> select index_name,partition_name,status from user_ind_partitions ;

INDEX_NAME                     PARTITION_NAME                 STATUS
------------------------------ ------------------------------ --------
INV_NO_IX                      P1                             USABLE
INV_NO_IX                      P0                             UNUSABLE

--此时如果通过inv_no查询分区p1,则会使用索引
SQL> select * from  inv_history where inv_date=to_date('2005-01-01','yyyy-mm-dd') and inv_no=1;

    INV_NO INV_DATE     INV_AMT
---------- --------- ----------
         1 01-JAN-05       1000
         1 01-JAN-05       1000


Execution Plan
----------------------------------------------------------
Plan hash value: 2903314601

------------------------------------------------------------------------------------------------------------------
| Id  | Operation                          | Name        | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                   |             |     2 |    32 |     5   (0)| 00:00:01 |       |       |
|   1 |  PARTITION RANGE SINGLE            |             |     2 |    32 |     5   (0)| 00:00:01 |     2 |     2 |
|*  2 |   TABLE ACCESS BY LOCAL INDEX ROWID| INV_HISTORY |     2 |    32 |     5   (0)| 00:00:01 |     2 |     2 |
|*  3 |    INDEX RANGE SCAN                | INV_NO_IX   |     2 |       |     3   (0)| 00:00:01 |     2 |     2 |
------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("INV_DATE"=TO_DATE(' 2005-01-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))
   3 - access("INV_NO"=1)


Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          6  consistent gets
          2  physical reads
          0  redo size
        739  bytes sent via SQL*Net to client
        519  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          2  rows processed

--而查询partition p0时,由于相应的索引分区为unusable状态,不会使用索引,但不影响查询
SQL> select * from  inv_history where inv_date=to_date('2004-01-01','yyyy-mm-dd') and inv_no=1;

    INV_NO INV_DATE     INV_AMT
---------- --------- ----------
         1 01-JAN-04       1000
         1 01-JAN-04       1000


Execution Plan
----------------------------------------------------------
Plan hash value: 3216071522

------------------------------------------------------------------------------------------------------
| Id  | Operation              | Name        | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT       |             |     2 |    32 |   347   (2)| 00:00:05 |       |       |
|   1 |  PARTITION RANGE SINGLE|             |     2 |    32 |   347   (2)| 00:00:05 |     1 |     1 |
|*  2 |   TABLE ACCESS FULL    | INV_HISTORY |     2 |    32 |   347   (2)| 00:00:05 |     1 |     1 |
------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("INV_NO"=1 AND "INV_DATE"=TO_DATE(' 2004-01-01 00:00:00', 'syyyy-mm-dd
              hh24:mi:ss'))


Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
       1213  consistent gets
          0  physical reads
          0  redo size
        739  bytes sent via SQL*Net to client
        519  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          2  rows processed

--如果再次将partition p1设置为unusable,那么该分区索引对应的段将被删除
SQL> alter index INV_NO_IX   modify partition p1 unusable;

Index altered.

SQL> select index_name,partition_name,status from user_ind_partitions ;

INDEX_NAME                     PARTITION_NAME                 STATUS
------------------------------ ------------------------------ --------
INV_NO_IX                      P1                             UNUSABLE
INV_NO_IX                      P0                             UNUSABLE

SQL> select segment_name,segment_type,partition_name,bytes/1024/1024 from user_segments;

SEGMENT_NAME                   SEGMENT_TYPE       PARTITION_NAME                 BYTES/1024/1024
------------------------------ ------------------ ------------------------------ ---------------
TEST                           TABLE                                                           3
INV_HISTORY                    TABLE PARTITION    P0                                          10
INV_HISTORY                    TABLE PARTITION    P1                                     

你可能感兴趣的:(12c)