Oracle 分区索引介绍和实例演示_oracle

分区索引(或索引分区)主要是针对分区表而言的。随着数据量的不断增长,普通的堆表需要转换到分区表,其索引呢,则对应的转换到分区索引。分区索引的好处是显而易见的。就是简单地把一个索引分成多个片断,在获取所需数据时,只需要访问更小的索引片断(块)即可实现。同时把分区放在不同的表空间可以提高分区的可用性和可靠性。本文主要描述了分区索引的相关特性并给出演示示例。

1、分区索引的相关概念

a、分区索引的几种方式:表被分区而索引未被分区;表未被分区,而索引被分区;表和索引都被分区
b、分区索引可以分为本地分区索引以及全局分区索引

本地分区索引:

   本地分区索引信息的存放依赖于父表分区。也就是说对于本地索引一定是基于分区表创建的。
   缺省情况下,创建本地索引时,如未指定索引存放表空间,会自动将本地索引存放到数据所在分区定义时的表空间。
   本地索引的分区机制和表的分区机制一样,本地索引可以是是B树索引或位图索引。
   本地索引是对单个分区的,每个分区索引只指向一个表分区,为对等分区。
   本地索引支持分区独立性,因此对于这些单独的分区增加,截取,删除,分割,脱机等处理无需同时删除或重建。
   本地索引多应用于数据仓库环境中。
     
全局分区索引:

   全局分区索引时分区表和全局索引的分区机制不一样,在创建时必须定义分区键的范围和值。
   全局分区索引在创建时应指定Global关键字且全局分区索引只能是B树索引。
   全局索引可以分区,也可以是不分区索引,全局索引必须是前缀索引,即索引列必须包含分区键。
   全局索引分区中,一个分区索引能指向n个表分区,同时,一个表分区,也可能指向n个索引分区。
   默认情况下全局索引对于分区增加,截取,删除,分割等都必须重建或修改时指定update global indexs。
   全局分区索引只按范围或者散列hash分区。
   全局分区索引多应用于oltp系统中。
 
c、有前缀索引和无前缀索引

本地和全局分区索引又分为两个子类型即有前缀索引和无前缀索引。
前缀和非前缀索引都可以支持索引分区消除,前提是查询的条件中包含索引分区键。
有前缀索引:
   有前缀索引包含了分区键,即分区键列被包含在索引中。
   有前缀索引支持本地分区索引以及全局分区索引。
无前缀索引:
   无前缀索引即没有把分区键的前导列作为索引的前导列。
   无前缀索引仅仅支持本地分区索引。  

2、本地分区索引演示

复制代码 代码如下:

--环境
SQL> select * from v$version where rownum<2;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bi

SQL> create user leshami identified by xxx;

SQL> grant dba to leshami;

--创建演示需要用到的表空间
SQL> create tablespace tbs_tmp datafile '/u02/database/SYBO2/oradata/tbs_tmp.dbf' size 10m autoextend on;

SQL> alter user leshami default tablespace tbs_tmp;

SQL> create tablespace tbs1 datafile '/u02/database/SYBO2/oradata/tbs1.dbf' size 10m autoextend on;

SQL> create tablespace tbs2 datafile '/u02/database/SYBO2/oradata/tbs2.dbf' size 10m autoextend on;

SQL> create tablespace tbs3 datafile '/u02/database/SYBO2/oradata/tbs3.dbf' size 10m autoextend on;

SQL> create tablespace idx1 datafile '/u02/database/SYBO2/oradata/idx1.dbf' size 10m autoextend on;

SQL> create tablespace idx2 datafile '/u02/database/SYBO2/oradata/idx2.dbf' size 10m autoextend on;

SQL> create tablespace idx3 datafile '/u02/database/SYBO2/oradata/idx3.dbf' size 10m autoextend on;

SQL> conn leshami/xxx

-- 创建一个lookup表
CREATE TABLE lookup (
  id            NUMBER(10),
  description   VARCHAR2(50)
);

--添加主键约束
ALTER TABLE lookup ADD (
  CONSTRAINT lookup_pk PRIMARY KEY (id)
);

--插入数据
INSERT INTO lookup (id, description) VALUES (1, 'ONE');
INSERT INTO lookup (id, description) VALUES (2, 'TWO');
INSERT INTO lookup (id, description) VALUES (3, 'THREE');
COMMIT;

CREATE TABLE big_table (
  id            NUMBER(10),
  created_date  DATE,
  lookup_id     NUMBER(10),
  data          VARCHAR2(50)
)
PARTITION BY RANGE (created_date)
(PARTITION big_table_2012 VALUES LESS THAN (TO_DATE('01/01/2013', 'DD/MM/YYYY')) tablespace tbs1,
 PARTITION big_table_2013 VALUES LESS THAN (TO_DATE('01/01/2014', 'DD/MM/YYYY')) tablespace tbs2,
 PARTITION big_table_2014 VALUES LESS THAN (MAXVALUE)tablespace tbs3 ) ;
 
--填充数据到分区表
DECLARE
  l_lookup_id    lookup.id%TYPE;
  l_create_date  DATE;
BEGIN
  FOR i IN 1 .. 10000 LOOP
    IF MOD(i, 3) = 0 THEN
      l_create_date := ADD_MONTHS(SYSDATE, -24);
      l_lookup_id   := 2;
    ELSIF MOD(i, 2) = 0 THEN
      l_create_date := ADD_MONTHS(SYSDATE, -12);
      l_lookup_id   := 1;
    ELSE
      l_create_date := SYSDATE;
      l_lookup_id   := 3;
    END IF;
   
    INSERT INTO big_table (id, created_date, lookup_id, data)
    VALUES (i, l_create_date, l_lookup_id, 'This is some data for ' || i);
  END LOOP;
  COMMIT;
END;
/

--未指定索引分区及存储表空间情形下创建索引
SQL> CREATE INDEX bita_created_date_i ON big_table(created_date) LOCAL;

Index created.

SQL> select index_name, partitioning_type, partition_count from user_part_indexes;

INDEX_NAME                     PARTITI PARTITION_COUNT
------------------------------ ------- ---------------
BITA_CREATED_DATE_I            RANGE                 3

--Author : Leshami

--从下面的查询可知,索引直接存放到分表表对应的表空间
SQL> select partition_name, high_value, tablespace_name from user_ind_partitions;

PARTITION_NAME                 HIGH_VALUE                               TABLESPACE_NAME
------------------------------ ---------------------------------------- ------------------------------
BIG_TABLE_2014                 MAXVALUE                                 TBS3
BIG_TABLE_2013                 TO_DATE(' 2014-01-01 00:00:00', 'SYYYY-M TBS2
                               M-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA

BIG_TABLE_2012                 TO_DATE(' 2013-01-01 00:00:00', 'SYYYY-M TBS1
                               M-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA

--删除索引
SQL> drop index bita_created_date_i;

--指定索引分区名表空间名创建索引
SQL> CREATE INDEX bita_created_date_i
  2     ON big_table (created_date)
  3     LOCAL (
  4        PARTITION idx_2012 TABLESPACE idx1,
  5        PARTITION idx_2013 TABLESPACE idx2,
  6        PARTITION idx_2014 TABLESPACE idx3)
  7     PARALLEL 3;

Index created.

SQL> select partition_name, high_value, tablespace_name from user_ind_partitions;

PARTITION_NAME                 HIGH_VALUE                               TABLESPACE_NAME
------------------------------ ---------------------------------------- ------------------------------
IDX_2014                       MAXVALUE                                 IDX3
IDX_2013                       TO_DATE(' 2014-01-01 00:00:00', 'SYYYY-M IDX2
                               M-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA

IDX_2012                       TO_DATE(' 2013-01-01 00:00:00', 'SYYYY-M IDX1
                               M-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA

SQL> select * from big_table where rownum<2;

        ID CREATED_  LOOKUP_ID DATA
---------- -------- ---------- --------------------------------------------------
      1413 20120625          2 This is some data for 1413

--查看local index是否被使用,从下面的执行计划中可知,索引被使用,支持分区消除     
SQL> set autot trace exp;
SQL> select * from big_table where created_date=to_date('20120625','yyyymmdd');

Execution Plan
----------------------------------------------------------
Plan hash value: 2556877094

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

3、全局分区索引演示

复制代码 代码如下:

--为表添加主键
SQL> ALTER TABLE big_table ADD (
  2    CONSTRAINT big_table_pk PRIMARY KEY (id)
  3  );

Table altered.      

SQL> select index_name,index_type,tablespace_name,global_stats,partitioned
  2  from user_indexes where index_name='BIG_TABLE_PK';

INDEX_NAME                     INDEX_TYPE                  TABLESPACE_NAME                GLO PAR
------------------------------ --------------------------- ------------------------------ --- ---
BIG_TABLE_PK                   NORMAL                      TBS_TMP                        YES NO

SQL> set autot trace exp;                                                                                         
SQL> select * from big_table where id=1412;                                                                       
                                                                                                                  
Execution Plan                                                                                                    
----------------------------------------------------------                                                        
Plan hash value: 2662411593                                                                                       
                                                                                                                  
-------------------------------------------------------------------------------------------------------------------
| Id  | Operation                          | Name         | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
-------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                   |              |     1 |    62 |     2   (0)| 00:00:01 |       |       |
|   1 |  TABLE ACCESS BY GLOBAL INDEX ROWID| BIG_TABLE    |     1 |    62 |     2   (0)| 00:00:01 | ROWID | ROWID |
|*  2 |   INDEX UNIQUE SCAN                | BIG_TABLE_PK |     1 |       |     1   (0)| 00:00:01 |       |       |
-------------------------------------------------------------------------------------------------------------------
--如上,在其执行计划中,Pstart与Pstop都为ROWID
--出现了GLOBAL INDEX ROWID,我们添加主键时并未指定Global,但其执行计划表明执行了全局索引访问
--这个地方有待证实,对于分区表,非分区键上的主键或唯一索引是否一定是全局索引

SQL> drop index bita_created_date_i;

--下面创建全局索引,创建时需要指定分区键的范围和值
SQL> CREATE INDEX bita_created_date_i
   ON big_table (created_date)
   GLOBAL PARTITION BY RANGE (created_date)
      (
         PARTITION
            idx_1 VALUES LESS THAN (TO_DATE ('01/01/2013', 'DD/MM/YYYY'))
            TABLESPACE idx1,
         PARTITION
            idx_2 VALUES LESS THAN (TO_DATE ('01/01/2014', 'DD/MM/YYYY'))
            TABLESPACE idx2,
         PARTITION idx_3 VALUES LESS THAN (maxvalue) TABLESPACE idx3);

SQL> select index_name, partitioning_type, partition_count,locality from user_part_indexes;

INDEX_NAME                     PARTITI PARTITION_COUNT LOCALI
------------------------------ ------- --------------- ------
BITA_CREATED_DATE_I_G          RANGE                 3 GLOBAL

SQL> select partition_name, high_value, tablespace_name from user_ind_partitions;

PARTITION_NAME                 HIGH_VALUE             TABLESPACE_NAME
------------------------------ --------------------- ------------------------------
IDX_1                          TO_DATE(' 2013-01-01  IDX1
IDX_2                          TO_DATE(' 2014-01-01  IDX2
IDX_3                          MAXVALUE              IDX3 

--下面是其执行计划,可以看出支持分区消除
SQL> set autot trace exp;
SQL> select * from big_table where created_date=to_date('20130625','yyyymmdd');

Execution Plan
----------------------------------------------------------
Plan hash value: 1378264218

---------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                           | Name                | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
---------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |                     |     1 |    41 |     2   (0)| 00:00:01 |       |       |
|   1 |  PARTITION RANGE SINGLE             |                     |     1 |    41 |     2   (0)| 00:00:01 |     2 |     2 |
|   2 |   TABLE ACCESS BY GLOBAL INDEX ROWID| BIG_TABLE           |     1 |    41 |     2   (0)| 00:00:01 |     2 |     2 |
|*  3 |    INDEX RANGE SCAN                 | BITA_CREATED_DATE_I |     1 |       |     1   (0)| 00:00:01 |     2 |     2 |
---------------------------------------------------------------------------------------------------------------------------

--以下为范围查询,Pstart为1,Pstop为2,同样支持分区消除
SQL> select * from big_table                                                              
  2  where created_date>=to_date('20120625','yyyymmdd') and created_date<=to_date('20130625','yyyymmdd');

Execution Plan
----------------------------------------------------------
Plan hash value: 213633793

------------------------------------------------------------------------------------------------------
| Id  | Operation                | Name      | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT         |           |  3334 |   133K|    14   (0)| 00:00:01 |       |       |
|   1 |  PARTITION RANGE ITERATOR|           |  3334 |   133K|    14   (0)| 00:00:01 |     1 |     2 |
|*  2 |   TABLE ACCESS FULL      | BIG_TABLE |  3334 |   133K|    14   (0)| 00:00:01 |     1 |     2 |
------------------------------------------------------------------------------------------------------

时间: 2024-09-08 11:39:37

Oracle 分区索引介绍和实例演示_oracle的相关文章

Oracle RAC环境下的阻塞(blocking blocked)介绍和实例演示_oracle

RAC环境下的阻塞不同于单实例情形,因为我们需要考虑到位于不同实例的session.也就是说之前查询的v$session,v$lock相应的应变化为全局范围来查找.本文提供了2个查询脚本,并给出实例演示那些session为阻塞者,哪些为被阻塞者.有关阻塞的概念以及单实例环境下的阻塞请参考:Oracle 阻塞(blocking blocked) 1.演示环境 scott@DEVDB> select * from v$version where rownum<2; BANNER ---------

Oracle 阻塞(blocking blocked)介绍和实例演示_oracle

阻塞是DBA经常碰到的情形,尤其是不良的应用程序设计的阻塞将导致性能严重下降直至数据库崩溃.对DBA而言,有必要知道如何定位到当前系统有哪些阻塞,到底谁是阻塞者,谁是被阻塞者.本文对此给出了描述并做了相关演示. 1.阻塞及其类型 a.什么是阻塞    一个会话持有某个资源的锁,而另一个会话在请求这个资源,就会出现阻塞(blocking).也就是说新的会话会被挂起,直到持有锁的会话放弃锁定的资源.大多数情况下,在一个交互式应用中被严重阻塞,即可表明应用逻辑有问题,这才是阻塞的根源. b.阻塞得类型

数据-oracle 分区索引效率问题

问题描述 oracle 分区索引效率问题 有A,B两张表,都加了range的分区索引,表空间什么都是一样的,在同一个分区下面 A的数据量和B的数据量是一样多的,但是查询的时候A的查询效率要慢很多,请问大家能帮我分析一下还有什么原因会导致这个结果吗?谢谢 解决方案 信息量实在太少,据你所说,AB两表都一样,那完全没道理查询效率不同.建议提供更详细的资料,如AB表的建表语句. 还有就是从sql角度出发,对sql进行explain

深入oracle分区索引的详解_oracle

表可以按range.hash.list分区,表分区后,其上的索引和普通表上的索引有所不同,oracle对于分区表上的索引分为2类,即局部索引和全局索引,下面分别对这2种索引的特点和局限性做个总结.局部索引local index1.局部索引一定是分区索引,分区键等同于表的分区键,分区数等同于表的分区数,一句话,局部索引的分区机制和表的分区机制一样.2.如果局部索引的索引列以分区键开头,则称为前缀局部索引.3.如果局部索引的列不是以分区键开头,或者不包含分区键列,则称为非前缀索引.4.局部索引只能依

Oracle 分区索引

    分区索引(或索引分区)主要是针对分区表而言的.随着数据量的不断增长,普通的堆表需要转换到分区表,其索引呢,则对应的转换到分区索引.分区索引的好处是显而易见的.就是简单地把一个索引分成多个片断,在获取所需数据时,只需要访问更小的索引片断(块)即可实现.同时把分区放在不同的表空间可以提高分区的可用性和可靠性.本文主要描述了分区索引的相关特性并给出演示示例.   1.分区索引的相关概念a.分区索引的几种方式:表被分区而索引未被分区:表未被分区,而索引被分区:表和索引都被分区b.分区索引可以分为

oracle索引介绍(图文详解)_oracle

对于数据库来说,索引是一个必选项,但对于现在的各种大型数据库来说,索引可以大大提高数据库的性能,以至于它变成了数据库不可缺少的一部分. 索引分类:逻辑分类single column or concatenated  对一列或多列建所引unique or nonunique 唯一的和非唯一的所引,也就是对某一列或几列的键值(key)是否是唯一的.Function-based  基于某些函数索引,当执行某些函数时需要对其进行计算,可以将某些函数的计算结果事先保存并加以索引,提高效率. Doman 

Oracle并行操作之并行查询实例解析_oracle

Oracle数据库的并行操作特性,其本质上就是强行榨取除数据库服务器空闲资源(主要是CPU资源),对一些高负荷大数据量数据进行分治处理.并行操作是一种非确定性的优化策略,在选择的时候需要小心对待.目前,使用并行操作特性的主要有下面几个方面: Parallel Query:并行查询,使用多个操作系统级别的Server Process来同时完成一个SQL查询: Parallel DML:并行DML操作.类似于Parallel Query.当要对大数据量表进行DML操作,如insert.update和

Oracle Local VS Global分区索引简介

在Oracle中,索引和表一样也可以分区.有两种类型的分区索引,本地分区索引(Local )和全局分区索引(Global). 1.本地索引(Local) 本地分区索引使用 LOCAL关键字创建,其分区边界与表相同(即与每个表分区相关联都有一个索引分区),下面 是一个本地分区索引的例子: create table sales_par partitioned by range (year) ( partition p_2009 values less than (2010) partition p_

Oracle中一个通过添加本地分区索引提高SQL性能的案例

今天接到同事求助,说有一个select query,在Oracle上要跑一分多钟,他希望能在5s内 出结果,该sql如下: Select /*+ parallel(src, 8) */ distinct src.systemname as systemname , src.databasename as databasename , src.tablename as tablename , src.username as username from <strong>meta_dbql_tabl