zoukankan      html  css  js  c++  java
  • 【转】分区表索引实践案例

     今天对分区表的索引(包括本地分区索引、全局分区索引、非分区索引)进行试验测试.
    =================================================================================================
                                                                     分区索引基础知识梳理
    =================================================================================================
    分区表的全局索引图示如下:

    创建语法为:
    CREATE [url=]INDEX[/url] INX_TAB_PARTITION_COL1 ON TABLE_PARTITION(COL1)
      GLOBAL PARTITION BY RANGE(COL1)
             PARTITION IDX_P1 values less than (1000000),
             PARTITION IDX_P2 values less than (2000000),
             PARTITION IDX_P3 values less than (MAXVALUE)
      )
    LOCAL索引结构图如下示:

    创建语法为:
    CREATE INDEX INX_TAB_PARTITION_COL1 ON TABLE_PARTITION(COL1) LOCAL;
    也可按照分区表的的分区结构给与一一定义,索引的分区将得到重命名。
    分区上的位图索引只能为LOCAL索引,不能为GLOBAL全局索引。
    =================================================================================================

    分区索引分为本地(local index)索引和全局索引(global index)。
    --------------->>官方指南:

    Local Partitioned Indexes

    In a local partitioned index, the index is partitioned on the same columns, with the same number of partitions and the same partition bounds as its table. Each index partition is associated with exactly one partition of the underlying table, so that all keys in an index partition refer only to rows stored in a single table partition. In this way, the database automatically synchronizes index partitions with their associated table partitions, making each table-index pair independent.

    Local partitioned indexes are common in data warehousing environments. Local indexes offer the following advantages:

    • Availability is increased because actions that make data invalid or unavailable in a partition affect this partition only.

    • Partition maintenance is simplified. When moving a table partition, or when data ages out of a partition, only the associated local index partition must be rebuilt or maintained. In a global index, all index partitions must be rebuilt or maintained.

    • If point-in-time recovery of a partition occurs, then the indexes can be recovered to the recovery time (see "Data File Recovery"). The entire index does not need to be rebuilt.

    Example 4-4 shows the creation statement for the partitioned hash_sales table, using the prod_id column as partition key. Example 4-5 creates a local partitioned index on the time_id column of the hash_sales table.

    Example 4-5 Local Partitioned Index

    CREATE INDEX hash_sales_idx ON hash_sales(time_id) LOCAL;
    

    In Figure 4-4, the hash_products table has two partitions, so hash_sales_idx has two partitions. Each index partition is associated with a different table partition. Index partition SYS_P38 indexes rows in table partition SYS_P33, whereas index partition SYS_P39 indexes rows in table partition SYS_P34.



    ------------------>>注意区别差异:

    Global Partitioned Indexes

    A global partitioned index is a B-tree index that is partitioned independently of the underlying table on which it is created. A single index partition can point to any or all table partitions, whereas in a locally partitioned index, a one-to-one parity exists between index partitions and table partitions.

    In general, global indexes are useful for OLTP applications, where rapid access, data integrity, and availability are important. In an OLTP system, a table may be partitioned by one key, for example, the employees.department_id column, but an application may need to access the data with many different keys, for example, by employee_id or job_id. Global indexes can be useful in this scenario.

    You can partition a global index by range or by hash. If partitioned by range, then the database partitions the global index on the ranges of values from the table columns you specify in the column list. If partitioned by hash, then the database assigns rows to the partitions using a hash function on values in the partitioning key columns.

    As an illustration, suppose that you create a global partitioned index on the time_range_sales table from Example 4-2. In this table, rows for sales from 1998 are stored in one partition, rows for sales from 1999 are in another, and so on. Example 4-6 creates a global index partitioned by range on the channel_id column.

    Example 4-6 Global Partitioned Index

    CREATE INDEX time_channel_sales_idx ON time_range_sales (channel_id)
       GLOBAL PARTITION BY RANGE (channel_id)
          (PARTITION p1 VALUES LESS THAN (3),
           PARTITION p2 VALUES LESS THAN (4),
           PARTITION p3 VALUES LESS THAN (MAXVALUE));
    

    As shown in Figure 4-5, a global index partition can contain entries that point to multiple table partitions. Index partition p1 points to the rows with a channel_id of 2, index partition p2 points to the rows with a channel_id of 3, and index partition p3 points to the rows with a channel_id of 4 or 9.



    其中本地索引又可以分为有前缀(prefix)的索引和无前缀(nonprefix)的索引。而全局索引目前只支持有前缀的索引。B树索引和位图索引都可以分区,但是HASH索引不可以被分区。位图索引必须是本地索引。

    一:本地索引:创建了一个分区表后,如果需要在表上面创建索引,并且索引的分区机制和表的分区机制一样,那么这样的索引就叫做本地分区索引。本地索引是由ORACLE自动管理的,它分为有前缀的本地索引和无前缀的本地索引。什么叫有前缀的本地索引?有前缀的本地索引就是包含了分区键,并且将其作为引导列的索引。什么叫无前缀的本地索引?无前缀的本地索引就是没有将分区键的前导列作为索引的前导列的索引

    二:全局索引:与本地分区索引不同的是,全局分区索引的分区机制与表的分区机制不一样。全局分区索引全局分区索引只能是B树索引,到目前为止(10gR2),oracle只支持有前缀的全局索引。另外oracle不会自动的维护全局分区索引,当我们在对表的分区做修改之后,如果执行修改的语句不加上update global indexes的话,那么索引将不可用;
    三:分区索引不能够将其作为整体重建,必须对每个分区重建
    =================================================================================================
                                                                      创建分区表并插入数据
    =================================================================================================
    --创建基于日期的范围分区,分区子句未指定表空间时则位于缺省的表空间
    create table sal_range   
                (salesman_id number(5),
                salesman_name varchar2(30),
                sales_date date)
                partition by range (sales_date) 
                (
                partition sal_jan2000 values less than(to_date('2014-02-01',
                    'YYYY-MM-DD')),
                partition sal_feb2000 values less than(to_date('2014-03-01',
                    'YYYY-MM-DD')),
                partition sal_mar2000 values less than(to_date('2014-04-01',
                    'YYYY-MM-DD')),
                partition pmax values less than(maxvalue)
                );
    --创建本地分区索引
    create index sal_range_index_local on sal_range(sales_date) local
    (
    partition sal_jan2000_index,
    partition sal_feb2000_index,
    partition sal_mar2000_index,
    partition pmax_index
    );
    --插入数据
    begin
    for i in 1 .. 10 loop
    insert into sal_range values(i,'sal_name'||i,to_date('2013-12-31','YYYY-MM-DD')+i);
    end loop;
    commit;
    end; 

    begin
    for i in 1 .. 10 loop
    insert into sal_range values(i+10,'sal_name'||(i+10),to_date('2014-01-31','YYYY-MM-DD')+i);
    end loop;
    commit;
    end; 

    begin
    for i in 1 .. 10 loop
    insert into sal_range values(i+20,'sal_name'||(i+20),to_date('2014-02-28','YYYY-MM-DD')+i);
    end loop;
    commit;
    end; 
     
    begin
    for i in 1 .. 10 loop
    insert into sal_range values(i+30,'sal_name'||(i+30),to_date('2014-04-30','YYYY-MM-DD')+i);
    end loop;
    commit;
    end; 

    begin
    for i in 1 .. 10 loop
    insert into sal_range values(i+40,'sal_name'||(i+40),to_date('2014-03-31','YYYY-MM-DD')+i);
    end loop;
    commit;
    end;

    begin
    for i in 1 .. 10 loop
    insert into sal_range values(i+50,'sal_name'||(i+50),to_date('2014-04-30','YYYY-MM-DD')+i);
    end loop;
    commit;
    end;

    begin
    for i in 1 .. 10 loop
    insert into sal_range values(i+60,'sal_name'||(i+60),to_date('2014-05-31','YYYY-MM-DD')+i);
    end loop;
    commit;
    end;

    begin
    for i in 1 .. 10 loop
    insert into sal_range values(i+70,'sal_name'||(i+70),to_date('2014-06-30','YYYY-MM-DD')+i);
    end loop;
    commit;
    end;

    begin
    for i in 1 .. 10 loop
    insert into sal_range values(i+80,'sal_name'||(i+80),to_date('2014-07-31','YYYY-MM-DD')+i);
    end loop;
    commit;
    end;
    ---查询测试
    SQL> select * from sal_range partition(sal_jan2000);
     
    SALESMAN_ID SALESMAN_NAME                  SALES_DATE
    ----------- ------------------------------ -----------
              1 sal_name1                      2014-1-1
              2 sal_name2                      2014-1-2
              3 sal_name3                      2014-1-3
              4 sal_name4                      2014-1-4
              5 sal_name5                      2014-1-5
              6 sal_name6                      2014-1-6
              7 sal_name7                      2014-1-7
              8 sal_name8                      2014-1-8
              9 sal_name9                      2014-1-9
             10 sal_name10                     2014-1-10
     
    SQL> select * from sal_range partition(sal_feb2000);
     
    SALESMAN_ID SALESMAN_NAME                  SALES_DATE
    ----------- ------------------------------ -----------
             11 sal_name11                     2014-2-1
             12 sal_name12                     2014-2-2
             13 sal_name13                     2014-2-3
             14 sal_name14                     2014-2-4
             15 sal_name15                     2014-2-5
             16 sal_name16                     2014-2-6
             17 sal_name17                     2014-2-7
             18 sal_name18                     2014-2-8
             19 sal_name19                     2014-2-9
             20 sal_name20                     2014-2-10
    ======================================================================
    --创建基于值范围的分区,分区子句未指定表空间时则位于缺省的表空间(此表不作为试验表,只是简单实现对比) 
                create table num_range      
                (num_id number,ename varchar2(50))
                partition by range (num_id)
                (
                    partition p1 values less than (10),
                    partition p2 values less than (20),
                    partition p3 values less than (30),
                    partition p4 values less than (maxvalue)
                );
    --插入数据
    begin
    for i in 1 .. 30 loop
    insert into num_range values(i,'num_range'||i);
    end loop;
    commit;
    end;
    --查询
    select * from num_range;
    select * from num_range partition(p1);
    =============================================================================
                                                  创建全局分区索引
     =============================================================================

    --创建分区索引(只有在分区表上才可以)
    create index num_range_index on num_range(num_id) local;
    --创建本地分区的唯一索引时,索引必须包括分区列
    create unique index num_range_uniq_index on num_range(num_id,ename) local;
    --创建本地分区索引
    create index sal_range_index_global on sal_range(salesman_id) global
    partition by range(salesman_id)
    (
    partition sal_range_10 values less than(11),
    partition sal_range_20 values less than(31),
    partition sal_range_30 values less than(41),
    partition sal_range_max values less than(maxvalue)
    );
    SQL> select partition_name,status from user_ind_partitions where index_name='SAL_RANGE_INDEX_GLOBAL';
     
    PARTITION_NAME                 STATUS
    ------------------------------ --------
    SAL_RANGE_10                   USABLE
    SAL_RANGE_20                   USABLE
    SAL_RANGE_30                   USABLE
    SAL_RANGE_MAX                  USABLE

    ===================================================================================
                                                           创建本地分区索引
     ===================================================================================
    全局分区索引实质上意味着该索引与数据表有不同的分区方案,且是基于分区表的一个或一组列进行分区的。主要是为了提高数据库中的数据查询 的性能.
    create index sal_range_index_local on sal_range(sales_date) local
    (
    partition sal_jan2000_index,
    partition sal_feb2000_index,
    partition sal_mar2000_index,
    partition pmax_index
    );
    --查询
    SQL> select partition_name,status from user_ind_partitions where index_name='SAL_RANGE_INDEX_GLOBAL';
     
    PARTITION_NAME                 STATUS
    ------------------------------ --------
    SAL_RANGE_10                   USABLE
    SAL_RANGE_20                   USABLE
    SAL_RANGE_30                   USABLE
    SAL_RANGE_MAX                  USABLE
    --注意:删除全局分区索引的部分分区后,如果被包含分区包含索引条目,上限比它高的相邻分区将被标记为不可用,且必须为索引指定一个maxvalue,这样就能保证新插入的数据将在全局分区索引中有地方保存,否则会报错如下:
    ---->>
    SQL 错误: ORA-14021: 必须指定所有列的 MAXVALUE
    14021. 00000 -  "MAXVALUE must be specified for all columns"
    *Cause:    In the VALUES LESS THAN clause for the highest (last) partition
               of a GLOBAL index, MAXVALUE must be specified for all columns
    *Action:   Ensure that VALUES LESS THAN clause for the last partition of a
               GLOBAL index has MAXVALUE specified for all columns

    alter index sal_range_index_global drop partition sal_range_20;
    --查询
    SQL> select partition_name,status from user_ind_partitions where index_name='SAL_RANGE_INDEX_GLOBAL';
     
    PARTITION_NAME                 STATUS
    ------------------------------ --------
    SAL_RANGE_10                   USABLE
    SAL_RANGE_30                   UNUSABLE
    SAL_RANGE_MAX                  USABLE

    ===================================================================================
                                                    维护分区表的索引
    ===================================================================================
    (1)添加分区:
    alter table sal_range drop partition pmax;
    alter table sal_range add partition sal_apr2000 values less than(to_date('2014-05-01','YYYY-MM-DD'));
    --插入201404数据
    begin
    for i in 1 .. 10 loop
    insert into sal_range values(i+40,'sal_name'||(i+40),to_date('2014-03-31','YYYY-MM-DD')+i);
    end loop;
    commit;
    end;
    --添加分区后确定操作对表上索引的影响:
    ----->>不影响本地分区索引、全局分区索引和非分区索引
    SQL> select t1.index_name,t1.partition_name,t1.status from user_ind_partitions t1 where t1.index_name in (
      2  select index_name from user_indexes t2 where t2.table_name='SAL_RANGE')order by 1,2,3;
     
    INDEX_NAME                               PARTITION_NAME               STATUS
    ------------------------------                   ------------------------------           --------
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_10                    USABLE
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_20                    USABLE
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_30                    USABLE
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_MAX                  USABLE
    SAL_RANGE_INDEX_LOCAL           SAL_APR2000                        USABLE
    SAL_RANGE_INDEX_LOCAL           SAL_FEB2000_INDEX              USABLE
    SAL_RANGE_INDEX_LOCAL           SAL_JAN2000_INDEX              USABLE
    SAL_RANGE_INDEX_LOCAL           SAL_MAR2000_INDEX             USABLE

    (2)截断分区[不影响本地分区索引,非分区索引和全局分区索引均会标记为UNUSABLE]:
    alter table sal_range truncate partition(sal_apr2000);
    ---->>
    SQL> select t1.index_name,t1.partition_name,t1.status from user_ind_partitions t1 where t1.index_name in (
      2  select index_name from user_indexes t2 where t2.table_name='SAL_RANGE')order by 1,2,3;
     
    INDEX_NAME                     PARTITION_NAME                 STATUS
    ------------------------------ ------------------------------ --------
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_10                   UNUSABLE
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_20                   UNUSABLE
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_30                   UNUSABLE
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_MAX                UNUSABLE
    SAL_RANGE_INDEX_LOCAL          SAL_APR2000                       USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_FEB2000_INDEX              USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_JAN2000_INDEX              USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_MAR2000_INDEX              USABLE

    (3)移动分区:
    alter table sal_range move partition sal_apr2000 tablespace dawn;
    --->>被移动本地分区索引UNUSABLE,非分区索引和全局分区索引均会标记为UNUSABLE
    SQL> select t1.index_name,t1.partition_name,t1.status from user_ind_partitions t1 where t1.index_name in (
      2  select index_name from user_indexes t2 where t2.table_name='SAL_RANGE')order by 1,2,3;
     
    INDEX_NAME                     PARTITION_NAME                 STATUS
    ------------------------------ ------------------------------ --------
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_10                   UNUSABLE
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_20                   UNUSABLE
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_30                   UNUSABLE
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_MAX                  UNUSABLE
    SAL_RANGE_INDEX_LOCAL          SAL_APR2000                    UNUSABLE
    SAL_RANGE_INDEX_LOCAL          SAL_FEB2000_INDEX              USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_JAN2000_INDEX              USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_MAR2000_INDEX              USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_MAY2000                    USABLE

    (4)拆分分区[拆分分区最常见的原因是,需要简单添加一个分区,而它不是表最高端的分区,所以由拆分来实现,面不是添加分区来实现。由于新的分区以前不存在,就没有分区索引与之对应,所状态为UNUSABLE,其他分区状态正常,非分区索引和全局分区索引也会变为UNUSABLE]:
    ---->>
    alter table sal_range add partition pmax values less than(maxvalue);
    ---->>
    SQL> select t1.index_name,t1.partition_name,t1.status from user_ind_partitions t1 where t1.index_name in (
      2  select index_name from user_indexes t2 where t2.table_name='SAL_RANGE')order by 1,2,3;
     
    INDEX_NAME                     PARTITION_NAME                 STATUS
    ------------------------------ ------------------------------ --------
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_10                   UNUSABLE
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_20                   UNUSABLE
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_30                   UNUSABLE
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_MAX                  UNUSABLE
    SAL_RANGE_INDEX_LOCAL          PMAX                           USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_APR2000                    UNUSABLE
    SAL_RANGE_INDEX_LOCAL          SAL_FEB2000_INDEX              USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_JAN2000_INDEX              USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_MAR2000_INDEX              USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_MAY2000                    USABLE
    --先修复索引再进行拆分试验(本地分区索引rebuild,全局分区索引recreate):
    alter index SAL_RANGE_INDEX_LOCAL rebuild partition SAL_APR2000;
    alter table sal_range drop partition pmax;
    create index sal_range_index_global on sal_range(salesman_id) global
    partition by range(salesman_id)
    (
    partition sal_range_10 values less than(11),
    partition sal_range_20 values less than(31),
    partition sal_range_30 values less than(41),
    partition sal_range_max values less than(maxvalue)
    );
    ------>>所有索引状态正常:
    SQL> select t1.index_name,t1.partition_name,t1.status from user_ind_partitions t1 where t1.index_name in (
      2  select index_name from user_indexes t2 where t2.table_name='SAL_RANGE')order by 1,2,3;
     
    INDEX_NAME                     PARTITION_NAME                 STATUS
    ------------------------------ ------------------------------ --------
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_10                   USABLE
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_20                   USABLE
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_30                   USABLE
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_MAX                  USABLE
    SAL_RANGE_INDEX_LOCAL          PMAX                           USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_APR2000                    USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_FEB2000_INDEX              USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_JAN2000_INDEX              USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_MAR2000_INDEX              USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_MAY2000                    USABLE
    ---->>索引拆分(这里需要注意,只有新拆分的分区中有数据时状态才会是UNUSABLE):
    alter table sal_range split partition PMAX at(to_date('2014-07-01','YYYY-MM-DD')) into(partition sal_june2000,partition pmax);
    ---->>
    SQL> select t1.index_name,t1.partition_name,t1.status from user_ind_partitions t1 where t1.index_name in (
      2  select index_name from user_indexes t2 where t2.table_name='SAL_RANGE')order by 1,2,3;
     
    INDEX_NAME                     PARTITION_NAME                 STATUS
    ------------------------------ ------------------------------ --------
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_10                   UNUSABLE
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_20                   UNUSABLE
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_30                   UNUSABLE
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_MAX                 UNUSABLE
    SAL_RANGE_INDEX_LOCAL          PMAX                              UNUSABLE
    SAL_RANGE_INDEX_LOCAL          SAL_APR2000                       USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_FEB2000_INDEX              USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_JAN2000_INDEX              USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_JUNE2000                 UNUSABLE
    SAL_RANGE_INDEX_LOCAL          SAL_MAR2000_INDEX             USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_MAY2000                       USABLE

    (5)交换分区(被交换分区状态变为UNUSABLE,全局分区索引和非分区索引均变为UNUSABLE):
    --->>先创建分区交换表(sal_range_exch)
    create table sal_range_exch(salesman_id number(5),
                salesman_name varchar2(30),
                sales_date date);
    --交换分区
    alter table sal_range exchange partition sal_june2000 with table sal_range_exch;
    --->>分区交换后表索引信息:
    SQL> select t1.index_name,t1.partition_name,t1.status from user_ind_partitions t1 where t1.index_name in (
      2  select index_name from user_indexes t2 where t2.table_name='SAL_RANGE')order by 1,2,3;
     
    INDEX_NAME                     PARTITION_NAME                 STATUS
    ------------------------------ ------------------------------ --------
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_10                   UNUSABLE
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_20                   UNUSABLE
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_30                   UNUSABLE
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_MAX                  UNUSABLE
    SAL_RANGE_INDEX_LOCAL          PMAX                                    USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_APR2000                       USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_FEB2000_INDEX              USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_JAN2000_INDEX              USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_JUNE2000                      UNUSABLE
    SAL_RANGE_INDEX_LOCAL          SAL_MAR2000_INDEX              USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_MAY2000                       USABLE

    -->>校验交换效果
    SQL> select * from sal_range_exch;
     
    SALESMAN_ID SALESMAN_NAME                  SALES_DATE
    ----------- ------------------------------ -----------
             61 sal_name61                     2014-6-1
             62 sal_name62                     2014-6-2
             63 sal_name63                     2014-6-3
             64 sal_name64                     2014-6-4
             65 sal_name65                     2014-6-5
             66 sal_name66                     2014-6-6
             67 sal_name67                     2014-6-7
             68 sal_name68                     2014-6-8
             69 sal_name69                     2014-6-9
             70 sal_name70                     2014-6-10

    (6)删除分区(对其他本地分区索引有没影响,但全局分区索引和非分区索引状态均变为UNUSABLE):
    --->>删除前先修复所有分区正常:
    SQL> select t1.index_name,t1.partition_name,t1.status from user_ind_partitions t1 where t1.index_name in (
      2  select index_name from user_indexes t2 where t2.table_name='SAL_RANGE')order by 1,2,3;
     
    INDEX_NAME                     PARTITION_NAME                 STATUS
    ------------------------------ ------------------------------ --------
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_10                   USABLE
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_20                   USABLE
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_30                   USABLE
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_MAX                  USABLE
    SAL_RANGE_INDEX_LOCAL          PMAX                           USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_APR2000                    USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_FEB2000_INDEX              USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_JAN2000_INDEX              USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_JUNE2000                   USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_MAR2000_INDEX              USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_MAY2000                    USABLE
    --->>删除分区pmax后分区索引明细:
    alter table sal_range drop partition pmax;
    ----->>
    SQL> select t1.index_name,t1.partition_name,t1.status from user_ind_partitions t1 where t1.index_name in (
      2  select index_name from user_indexes t2 where t2.table_name='SAL_RANGE')order by 1,2,3;
     
    INDEX_NAME                     PARTITION_NAME                 STATUS
    ------------------------------ ------------------------------ --------
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_10                   UNUSABLE
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_20                   UNUSABLE
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_30                   UNUSABLE
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_MAX                  UNUSABLE
    SAL_RANGE_INDEX_LOCAL          SAL_APR2000                    USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_FEB2000_INDEX              USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_JAN2000_INDEX              USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_JUNE2000                   USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_MAR2000_INDEX              USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_MAY2000                    USABLE

    (7)合并分区:
    --->>前期分区情况:
    SQL> select t1.index_name,t1.partition_name,t1.status from user_ind_partitions t1 where t1.index_name in (
      2  select index_name from user_indexes t2 where t2.table_name='SAL_RANGE')order by 1,2,3;
     
    INDEX_NAME                     PARTITION_NAME                 STATUS
    ------------------------------ ------------------------------ --------
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_10                   USABLE
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_20                   USABLE
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_30                   USABLE
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_MAX                  USABLE
    SAL_RANGE_INDEX_LOCAL          PMAX                           USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_APR2000                    USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_FEB2000_INDEX              USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_JAN2000_INDEX              USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_JULY2000                   UNUSABLE
    SAL_RANGE_INDEX_LOCAL          SAL_JUNE2000                   USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_MAR2000_INDEX              USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_MAY2000                    USABLE
    --->>合并七月分区和max为max分区:
    alter table sal_range merge partitions sal_july2000,pmax into partition pmax;
    --->>操作用分区明细:
    SQL> select t1.index_name,t1.partition_name,t1.status from user_ind_partitions t1 where t1.index_name in (
      2  select index_name from user_indexes t2 where t2.table_name='SAL_RANGE')order by 1,2,3;
     
    INDEX_NAME                     PARTITION_NAME                 STATUS
    ------------------------------ ------------------------------ --------
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_10                   UNUSABLE
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_20                   UNUSABLE
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_30                   UNUSABLE
    SAL_RANGE_INDEX_GLOBAL         SAL_RANGE_MAX                  UNUSABLE
    SAL_RANGE_INDEX_LOCAL          PMAX                           UNUSABLE
    SAL_RANGE_INDEX_LOCAL          SAL_APR2000                    USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_FEB2000_INDEX              USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_JAN2000_INDEX              USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_JUNE2000                   USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_MAR2000_INDEX              USABLE
    SAL_RANGE_INDEX_LOCAL          SAL_MAY2000                    USABLE
    ==================================================================================
                                        注意事项
    ===================================================================================
    a1.查询user_indexes视图时,分区索引对应的状态是N/A(表示不可用)。只有基于索引分区最精细的数据字典视图(user_ind_partitions)的状态才会填入数据,如果查询的是子分区
       索引,则需查询user_ind_subpartitions;
    ------------------->>因为以前在这块东西曾经给我带来了不少麻烦,痛定思痛,总结如下,防患于未然,希望能帮到相关学友:

    图1
    注解:IDX_R_CAR_ALARM_STAT_MONTH和IDX_R_CAR_ALL_BASIC_MONTH是单分区表索引,中status值为:N/A,其余status值为N/A的都是复合分区表索引。
          在user_indexes中分区表索引状态均为N/A,只代表索引有效,并不能代表其是否正常
    ========================================================================================================

    图2
    注解:IDX_R_CAR_ALARM_STAT_MONTH和IDX_R_CAR_ALL_BASIC_MONTH是单分区表索引,在user_ind_partitions中status值才会正常表示,复合分区表索引均为N/A
    ========================================================================================================

    图3
    注解:复合分区表索引status 只能在user_ind_subpartitions中查询,非分区索引和单分区索引根本就不会在这数据字典里显示.
    ======================================================================================================
    a2.以上分区索引维护的各步试验过是先将全局索引先drop再create,本地分区索引采用类似alter index SAL_RANGE_INDEX_LOCAL rebuild partition pmax的脚本处理后再进行后     续试验.;
    a3.oracle对于本地分区索引的创建,如果创建分区,那么所有分区都会创建相应分区索引,即使你创建本地分区索引时指定的索引分区个小小于表真实分区个数,比如我的本地创建分区索引过程(只列举了四个分区,实际是有7个)。
    create index sal_range_index_local on sal_range(sales_date) local
    (
    partition sal_jan2000_index,
    partition sal_feb2000_index,
    partition sal_mar2000_index,
    partition pmax_index
    );
    如果采用简单方法类似:
    create index sal_range_index_local on sal_range(hire_date) tablespace dawn local.那么产生的索引分区名和表分区名默认是一样的.

    最后,关于分区表的相关试验案例请参考:http://blog.itpub.net/29119536/viewspace-1142363/
            关于分区表的基础知识请参考:http://blog.itpub.net/29119536/viewspace-1141934/

      原文:http://blog.itpub.net/29119536/viewspace-1145136/

  • 相关阅读:
    MYSQL转MSSQL
    SVN 服务器IP地址变更后客户端的修改
    gridview
    gridview外边距
    Android开发:自定义GridView/ListView数据源
    Android之Adapter用法总结
    collection set
    listview优化
    android应用开发全程实录-你有多熟悉listview
    android模块
  • 原文地址:https://www.cnblogs.com/ZeroTiny/p/5149158.html
Copyright © 2011-2022 走看看