探究Oracle 12c 中在同一个列上建立多个索引

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/seagal890/article/details/83032231

探究Oracle 12c 中在同一个列上建立多个索引

Oracle 12c允许在同一组列上建立多个索引,但是只有一个索引是可见的,并且所有索引在某些方面可以有不同。 

示例

Non-Partitioned Tables

例如,我们可以创建一个非分区表t1,并插入测试数据。

然后在 create_date列上创建一个索引;当第二次使用语句 

CREATE INDEX t1_idx2 ON t1(created_date) INVISIBLE;

在 created_date列上再次创建索引时,提示错误。

SQL> CREATE TABLE t1 (
  2    id            NUMBER,
  3    description   VARCHAR2(50),
  4    created_date  DATE
  5  );

表已创建。

已用时间:  00: 00: 00.08
SQL>
SQL> INSERT INTO t1 VALUES (1, 't1 ONE', TO_DATE('01/07/2014', 'DD/MM/YYYY'));

已创建 1 行。

已用时间:  00: 00: 00.03

SQL> INSERT INTO t1 VALUES (2, 't1 TWO', TO_DATE('01/07/2015', 'DD/MM/YYYY'));

已创建 1 行。

已用时间:  00: 00: 00.01


SQL> INSERT INTO t1 VALUES (3, 't1 THREE', TO_DATE('01/07/2016', 'DD/MM/YYYY'));

已创建 1 行。

已用时间:  00: 00: 00.00


SQL> COMMIT;

提交完成。

已用时间:  00: 00: 00.00
SQL> CREATE INDEX t1_idx1 ON t1(created_date) VISIBLE;

索引已创建。

已用时间:  00: 00: 00.01
SQL> CREATE INDEX t1_idx2 ON t1(created_date) INVISIBLE;
CREATE INDEX t1_idx2 ON t1(created_date) INVISIBLE
                           *
第 1 行出现错误:
ORA-01408: 此列列表已索引


已用时间:  00: 00: 00.06
SQL> CREATE BITMAP INDEX t1_idx3 ON t1(created_date) INVISIBLE;

索引已创建。

已用时间:  00: 00: 00.11
SQL>

但是可以使用这个语句在created_date列上来创建一个BITMAP类型的索引:

CREATE BITMAP INDEX t1_idx3 ON t1(created_date) INVISIBLE;

 Partitioned Tables

创建一个分区表t1:

SQL> DROP TABLE t1 PURGE;

表已删除。

SQL>
SQL> CREATE TABLE t1 (
  2    id            NUMBER,
  3    description   VARCHAR2(50),
  4    created_date  DATE
  5  )
  6  PARTITION BY RANGE (created_date) (
  7    PARTITION part_2014 VALUES LESS THAN (TO_DATE('01/01/2015', 'DD/MM/YYYY')) TABLESPACE users,
  8    PARTITION part_2015 VALUES LESS THAN (TO_DATE('01/01/2016', 'DD/MM/YYYY')) TABLESPACE users,
  9    PARTITION part_2016 VALUES LESS THAN (TO_DATE('01/01/2017', 'DD/MM/YYYY')) TABLESPACE users
 10  );

表已创建。

SQL>
SQL> INSERT INTO t1 VALUES (1, 't1 ONE', TO_DATE('01/07/2014', 'DD/MM/YYYY'));

已创建 1 行。

SQL> INSERT INTO t1 VALUES (2, 't1 TWO', TO_DATE('01/07/2015', 'DD/MM/YYYY'));

已创建 1 行。

SQL> INSERT INTO t1 VALUES (3, 't1 THREE', TO_DATE('01/07/2016', 'DD/MM/YYYY'));

已创建 1 行。

SQL> COMMIT;

提交完成。

SQL>

 在分区表t1上创建一个索引:

扫描二维码关注公众号,回复: 3690561 查看本文章
CREATE INDEX t1_idx1 ON t1(created_date) GLOBAL VISIBLE;
SQL> CREATE INDEX t1_idx1 ON t1(created_date) GLOBAL VISIBLE;

索引已创建。

SQL>

 在不同的分区上创建索引;

CREATE INDEX t1_idx2 ON t1(created_date) GLOBAL
PARTITION BY RANGE (created_date) (
  PARTITION t1_p1 VALUES LESS THAN (TO_DATE('01/01/2015', 'DD/MM/YYYY')) TABLESPACE users,
  PARTITION t1_p2 VALUES LESS THAN (TO_DATE('01/01/2016', 'DD/MM/YYYY')) TABLESPACE users,
  PARTITION t1_p3 VALUES LESS THAN (MAXVALUE) TABLESPACE users
)
INVISIBLE;
SQL> CREATE INDEX t1_idx2 ON t1(created_date) GLOBAL
  2  PARTITION BY RANGE (created_date) (
  3    PARTITION t1_p1 VALUES LESS THAN (TO_DATE('01/01/2015', 'DD/MM/YYYY')) TABLESPACE users,
  4    PARTITION t1_p2 VALUES LESS THAN (TO_DATE('01/01/2016', 'DD/MM/YYYY')) TABLESPACE users,
  5    PARTITION t1_p3 VALUES LESS THAN (MAXVALUE) TABLESPACE users
  6  )
  7  INVISIBLE;

索引已创建。

SQL>
SQL> CREATE INDEX t1_idx3 ON t1(created_date) LOCAL INVISIBLE;

索引已创建。

SQL> CREATE BITMAP INDEX t1_idx4 ON t1(created_date) LOCAL INVISIBLE;

索引已创建。

SQL>

为什么要使用多索引?即为什么要在一个列上创建多个索引呢?

可以通过在一个列上创建不同的索引,通过改变索引的可见性(visible或者invisible)来测试索引的影响。

可以通过下面的查询来查看索引的可见性

SQL> -- Check visibility of indexes.
SQL> COLUMN index_name FORMAT A10
SQL> COLUMN index_type FORMAT A10
SQL> COLUMN partitioned FORMAT A12
SQL> COLUMN locality FORMAT A8
SQL> COLUMN visibility FORMAT A10
SQL>
SQL> SELECT a.index_name,
  2         a.index_type,
  3         a.partitioned,
  4         b.partitioning_type,
  5         b.locality,
  6         a.visibility
  7  FROM   user_indexes a
  8         LEFT OUTER JOIN user_part_indexes b ON a.index_name = b.index_name
  9  ORDER BY index_name;

INDEX_NAME INDEX_TYPE PARTITIONED  PARTITIONING_TYPE  LOCALITY VISIBILITY
---------- ---------- ------------ ------------------ -------- ----------
IDX_DEPTCO NORMAL     NO                                       VISIBLE
PY_DEPTNO

IDX_DEPTNO NORMAL     NO                                       VISIBLE
IDX_MGR    NORMAL     NO                                       VISIBLE
PK_DEPT    NORMAL     NO                                       VISIBLE
PK_EMP     NORMAL     NO                                       VISIBLE
T1_IDX1    NORMAL     NO                                       VISIBLE
T1_IDX2    NORMAL     YES          RANGE              GLOBAL   INVISIBLE
T1_IDX3    NORMAL     YES          RANGE              LOCAL    INVISIBLE
T1_IDX4    BITMAP     YES          RANGE              LOCAL    INVISIBLE
TEST_TAB_I NORMAL     NO                                       VISIBLE
D


已选择 10 行。

SQL>

看看查询中索引的使用情况。执行下面的查询,通过查看执行计划发现使用了索引,

SQL> SET AUTOTRACE TRACE EXPLAIN
SQL> SELECT *
  2  FROM   t1
  3  WHERE created_date = TO_DATE('01/07/2014', 'DD/MM/YYYY');

执行计划
----------------------------------------------------------
Plan hash value: 1106166644

----------------------------------------------------------------------------------------------------------------------
| Id  | Operation                                  | Name    | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
----------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                           |         |     1 |    49 |     1   (0)| 00:00:01 |       |       |
|   1 |  TABLE ACCESS BY GLOBAL INDEX ROWID BATCHED| T1      |     1 |    49 |     1   (0)| 00:00:01 |     1 |     1 |
|*  2 |   INDEX RANGE SCAN                         | T1_IDX1 |     1 |       |     1   (0)| 00:00:01 |       |       |
----------------------------------------------------------------------------------------------------------------------

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

   2 - access("CREATED_DATE"=TO_DATE(' 2014-07-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))

Note
-----
   - dynamic statistics used: dynamic sampling (level=2)

SQL>

改变索引的状态

SQL> -- Switch indexes.
SQL> ALTER INDEX t1_idx1 INVISIBLE;

索引已更改。

SQL> ALTER INDEX t1_idx2 VISIBLE;

索引已更改。

查看索引的状态是否改变: 

SQL> -- Check visibility of indexes.
SQL> SELECT a.index_name,
  2         a.index_type,
  3         a.partitioned,
  4         b.partitioning_type,
  5         b.locality,
  6         a.visibility
  7  FROM   user_indexes a
  8         LEFT OUTER JOIN user_part_indexes b ON a.index_name = b.index_name
  9  ORDER BY index_name;

INDEX_NAME INDEX_TYPE PARTITIONED  PARTITIONING_TYPE  LOCALITY VISIBILITY
---------- ---------- ------------ ------------------ -------- ----------
IDX_DEPTCO NORMAL     NO                                       VISIBLE
PY_DEPTNO

IDX_DEPTNO NORMAL     NO                                       VISIBLE
IDX_MGR    NORMAL     NO                                       VISIBLE
PK_DEPT    NORMAL     NO                                       VISIBLE
PK_EMP     NORMAL     NO                                       VISIBLE
T1_IDX1    NORMAL     NO                                       INVISIBLE
T1_IDX2    NORMAL     YES          RANGE              GLOBAL   VISIBLE
T1_IDX3    NORMAL     YES          RANGE              LOCAL    INVISIBLE
T1_IDX4    BITMAP     YES          RANGE              LOCAL    INVISIBLE
TEST_TAB_I NORMAL     NO                                       VISIBLE
D

执行查询,查看索引是否可用:

SQL> -- Test the index usage.
SQL> SET AUTOTRACE TRACE EXPLAIN
SQL>
SQL> SELECT *
  2  FROM   t1
  3  WHERE created_date = TO_DATE('01/07/2014', 'DD/MM/YYYY');

执行计划
----------------------------------------------------------
Plan hash value: 3769679070

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

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

   3 - access("CREATED_DATE"=TO_DATE(' 2014-07-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))

Note
-----
   - dynamic statistics used: dynamic sampling (level=2)

SQL>

改变索引的状态:

SQL> -- Switch indexes.
SQL> ALTER INDEX t1_idx3 INVISIBLE;

索引已更改。

SQL> ALTER INDEX t1_idx4 VISIBLE;
ALTER INDEX t1_idx4 VISIBLE
*
第 1 行出现错误:
ORA-14147: 同一列集上已存在定义的 VISIBLE 索引。


SQL>
SQL>
SQL> -- Check visibility of indexes.
SQL> SELECT a.index_name,
  2         a.index_type,
  3         a.partitioned,
  4         b.partitioning_type,
  5         b.locality,
  6         a.visibility
  7  FROM   user_indexes a
  8         LEFT OUTER JOIN user_part_indexes b ON a.index_name = b.index_name
  9  ORDER BY index_name;

INDEX_NAME INDEX_TYPE PARTITIONED  PARTITIONING_TYPE  LOCALITY VISIBILITY
---------- ---------- ------------ ------------------ -------- ----------
IDX_DEPTCO NORMAL     NO                                       VISIBLE
PY_DEPTNO

IDX_DEPTNO NORMAL     NO                                       VISIBLE
IDX_MGR    NORMAL     NO                                       VISIBLE
PK_DEPT    NORMAL     NO                                       VISIBLE
PK_EMP     NORMAL     NO                                       VISIBLE
T1_IDX1    NORMAL     NO                                       INVISIBLE
T1_IDX2    NORMAL     YES          RANGE              GLOBAL   VISIBLE
T1_IDX3    NORMAL     YES          RANGE              LOCAL    INVISIBLE
T1_IDX4    BITMAP     YES          RANGE              LOCAL    INVISIBLE
TEST_TAB_I NORMAL     NO                                       VISIBLE
D


已选择 10 行。

SQL>

猜你喜欢

转载自blog.csdn.net/seagal890/article/details/83032231