oracle 创建索引

索引的相关创建与使用

创建普通索引

 

SQL> select * from temp;

 

        ID NAME

---------- --------------------

      1456 sony

      1379 sony

      1568 lenovo

      1788 lenovo

 

 

SQL> desc user_ind_columns

Name                                      Null?    Type

 ----------------------------------------- -------- ----------------------------

 INDEX_NAME                                         VARCHAR2(30)

 TABLE_NAME                                         VARCHAR2(30)

 COLUMN_NAME                                        VARCHAR2(4000)

 COLUMN_POSITION                                    NUMBER

 COLUMN_LENGTH                                      NUMBER

 CHAR_LENGTH                                        NUMBER

 DESCEND                                            VARCHAR2(4)

查询表是否有索引

SQL> select index_name,column_name from user_ind_columns where table_name='TEMP';

 

no rows selected

创建索引

SQL> create index temp_id_i on temp(id);

 

Index created.

 

开启追踪

SQL> set autot trace exp

SQL> select * from temp where id=1379;

 

Execution Plan

----------------------------------------------------------

Plan hash value: 3945629271

 

--------------------------------------------------------------------------------

---------

 

| Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)| T

ime     |

 

--------------------------------------------------------------------------------

---------

 

|   0 | SELECT STATEMENT            |           |     1 |    25 |     2   (0)| 0

0:00:01 |

 

|   1 |  TABLE ACCESS BY INDEX ROWID| TEMP      |     1 |    25 |     2   (0)| 0

0:00:01 |

 

|*  2 |   INDEX RANGE SCAN          | TEMP_ID_I |     1 |       |     1   (0)| 0

0:00:01 |

 

--------------------------------------------------------------------------------

---------

 

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   2 - access("ID"=1379)

 

Note

-----

   - dynamic sampling used for this statement

 

SQL>

删除索引在查询

SQL> drop index temp_id_i;

 

Index dropped.

 

SQL> select * from temp where id=1379;

 

Execution Plan

----------------------------------------------------------

Plan hash value: 1896031711

 

--------------------------------------------------------------------------

| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |

--------------------------------------------------------------------------

|   0 | SELECT STATEMENT  |      |     1 |    25 |     3   (0)| 00:00:01 |

|*  1 |  TABLE ACCESS FULL| TEMP |     1 |    25 |     3   (0)| 00:00:01 |

--------------------------------------------------------------------------

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   1 - filter("ID"=1379)

 

Note

-----

   - dynamic sampling used for this statement

 

SQL>

 

 

 

建立排序索引

 

SQL> select * from temp;

 

        ID NAME                        SAL

---------- -------------------- ----------

      1456 sony                       1254

      1379 sony                       1106

      1568 lenovo                     1018

      1788 lenovo                     1758

 

SQL>

想要查询的语句

SQL> select * from temp where sal>1000 order by sal asc;

 

        ID NAME                        SAL

---------- -------------------- ----------

      1568 lenovo                     1018

      1379 sony                       1106

      1456 sony                       1254

      1788 lenovo                     1758

 

SQL>

创建升序索引

QL> create index temp_sal_i on temp(sal asc);

 

Index created.

 

SQL>

查看执行计划

SQL> set autot trace exp

SQL> select * from temp where sal>1100 order by sal asc;

 

Execution Plan

----------------------------------------------------------

Plan hash value: 1493261289

 

--------------------------------------------------------------------------------

----------

 

| Id  | Operation                   | Name       | Rows  | Bytes | Cost (%CPU)|

Time     |

 

--------------------------------------------------------------------------------

----------

 

|   0 | SELECT STATEMENT            |            |     3 |   114 |     2   (0)|

00:00:01 |

 

|   1 |  TABLE ACCESS BY INDEX ROWID| TEMP       |     3 |   114 |     2   (0)|

00:00:01 |

 

|*  2 |   INDEX RANGE SCAN          | TEMP_SAL_I |     3 |       |     1   (0)|

00:00:01 |

 

--------------------------------------------------------------------------------

----------

 

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   2 - access("SAL">1100)

       filter("SAL">1100)

 

 

SQL>

如果变为降序

SQL> select * from temp where sal>1100 order by sal desc;

 

Execution Plan

----------------------------------------------------------

Plan hash value: 3579856106

 

--------------------------------------------------------------------------------

-----------

 

| Id  | Operation                    | Name       | Rows  | Bytes | Cost (%CPU)|

 Time     |

 

--------------------------------------------------------------------------------

-----------

 

|   0 | SELECT STATEMENT             |            |     3 |   114 |     2   (0)|

 00:00:01 |

 

|   1 |  TABLE ACCESS BY INDEX ROWID | TEMP       |     3 |   114 |     2   (0)|

 00:00:01 |

 

|*  2 |   INDEX RANGE SCAN DESCENDING| TEMP_SAL_I |     3 |       |     1   (0)|

 00:00:01 |

 

--------------------------------------------------------------------------------

-----------

 

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   2 - access("SAL">1100)

       filter("SAL">1100)

 

 

SQL>

使索引不对表进行排序可以创建降序索引

SQL> drop index temp_sal_i;

 

Index dropped.

 

SQL> create index temp_sal_i on temp(sal desc);

 

Index created.

 

SQL> select * from temp where sal>1100 order by sal desc;

 

Execution Plan

----------------------------------------------------------

Plan hash value: 1493261289

 

--------------------------------------------------------------------------------

----------

 

| Id  | Operation                   | Name       | Rows  | Bytes | Cost (%CPU)|

Time     |

 

--------------------------------------------------------------------------------

----------

 

|   0 | SELECT STATEMENT            |            |     3 |   114 |     2   (0)|

00:00:01 |

 

|   1 |  TABLE ACCESS BY INDEX ROWID| TEMP       |     3 |   114 |     2   (0)|

00:00:01 |

 

|*  2 |   INDEX RANGE SCAN          | TEMP_SAL_I |     1 |       |     1   (0)|

00:00:01 |

 

--------------------------------------------------------------------------------

----------

 

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   2 - access(SYS_OP_DESCEND("SAL")<hextoraw('3df3ff') )<="" span="" style="word-wrap: break-word;">

       filter(SYS_OP_UNDESCEND(SYS_OP_DESCEND("SAL"))>1100 AND

              SYS_OP_DESCEND("SAL")<hextoraw('3df3ff') )<="" span="" style="word-wrap: break-word;">

 

Note

-----

   - dynamic sampling used for this statement

 

SQL>

 

创建不排序索引

创建不排序索引的前提是在要建索引的列必须是已经升序排序过的了

 

SQL> create table temp1 as select * from temp;

 

Table created.

截断表

SQL> truncate table temp1;

 

Table truncated.

插入数据并排序

SQL> insert into temp1 select * from temp order by id;

4 rows created.

 

SQL>

SQL> select * from temp1;

 

        ID NAME                        SAL

---------- -------------------- ----------

      1379 sony                       1106

      1456 sony                       1254

      1568 lenovo                     1018

      1788 lenovo                     1758

 

SQL>

创建不排序索引

SQL> create index temp1_id_i on temp1(id) nosort;

 

Index created.

 

SQL>

 

创建组合索引

注意事项:

要把去掉重复行之后个数少的列放前面 (如果是空值,就把空值最多的放在前面)

例:

SQL> select count(distinct(name)) from temp;

 

COUNT(DISTINCT(NAME))

---------------------

                    2

 

SQL> select count(distinct(sal)) from temp;

 

COUNT(DISTINCT(SAL))

--------------------

                   4

 

SQL>

所以 name列应放在sal列的前面

 

 

QL> select * from temp where name='sony' and sal=1106;

 

        ID NAME                        SAL

---------- -------------------- ----------

      1379 sony                       1106

 

SQL> create index temp_name_sal_i on temp(name,sal);

 

Index created.

 

SQL> set autot trace exp

SQL> select * from temp where name='sony' and sal=1106;

 

Execution Plan

----------------------------------------------------------

Plan hash value: 1649455405

 

--------------------------------------------------------------------------------

---------------

 

| Id  | Operation                   | Name            | Rows  | Bytes | Cost (%C

PU)| Time     |

 

--------------------------------------------------------------------------------

---------------

 

|   0 | SELECT STATEMENT            |                 |     1 |    38 |     2

(0)| 00:00:01 |

 

|   1 |  TABLE ACCESS BY INDEX ROWID| TEMP            |     1 |    38 |     2

(0)| 00:00:01 |

 

|*  2 |   INDEX RANGE SCAN          | TEMP_NAME_SAL_I |     1 |       |     1

(0)| 00:00:01 |

 

--------------------------------------------------------------------------------

---------------

 

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   2 - access("NAME"='sony' AND "SAL"=1106)

       filter(SYS_OP_DESCEND("SAL")=HEXTORAW('3DF3F8FF') )

 

 

SQL>

如果索引分开建在查询时只能用到一个索引

SQL> drop index temp_name_sal_i;

 

Index dropped.

 

SQL>

SQL> create index temp_name_i on temp(name);

 

Index created.

 

SQL>

SQL> create index temp_sal_i on temp(sal);

 

Index created.

 

SQL>

SQL> select * from temp where name='sony' and sal=1106;

 

Execution Plan

----------------------------------------------------------

Plan hash value: 1493261289

 

--------------------------------------------------------------------------------

----------

 

| Id  | Operation                   | Name       | Rows  | Bytes | Cost (%CPU)|

Time     |

 

--------------------------------------------------------------------------------

----------

 

|   0 | SELECT STATEMENT            |            |     1 |    38 |     2   (0)|

00:00:01 |

 

|*  1 |  TABLE ACCESS BY INDEX ROWID| TEMP       |     1 |    38 |     2   (0)|

00:00:01 |

 

|*  2 |   INDEX RANGE SCAN          | TEMP_SAL_I |     1 |       |     1   (0)|

00:00:01 |

 

--------------------------------------------------------------------------------

----------

 

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   1 - filter("NAME"='sony')

   2 - access("SAL"=1106)

 

创建无效索引

 

SQL> create index temp_name_i on temp(name) unusable;

 

Index created.

 

SQL>

SQL> select index_name,status from user_indexes;

 

INDEX_NAME                     STATUS

------------------------------ --------

TEMP_NAME_I                    UNUSABLE

TEMP1_ID_I                     VALID

SYS_C005242                    VALID

 

SQL>

SQL> set autot trace exp

SQL> select * from temp where name='sony';

 

Execution Plan

----------------------------------------------------------

Plan hash value: 1896031711

 

--------------------------------------------------------------------------

| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |

--------------------------------------------------------------------------

|   0 | SELECT STATEMENT  |      |     2 |    76 |     3   (0)| 00:00:01 |

|*  1 |  TABLE ACCESS FULL| TEMP |     2 |    76 |     3   (0)| 00:00:01 |

--------------------------------------------------------------------------

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   1 - filter("NAME"='sony')

 

 

SQL>

 

重建索引可以使其有效

SQL> alter index temp_name_i rebuild;

 

Index altered.

 

SQL> select * from temp where name='sony';

 

Execution Plan

----------------------------------------------------------

Plan hash value: 1257893614

 

--------------------------------------------------------------------------------

-----------

 

| Id  | Operation                   | Name        | Rows  | Bytes | Cost (%CPU)|

 Time     |

 

--------------------------------------------------------------------------------

-----------

 

|   0 | SELECT STATEMENT            |             |     2 |    76 |     2   (0)|

 00:00:01 |

 

|   1 |  TABLE ACCESS BY INDEX ROWID| TEMP        |     2 |    76 |     2   (0)|

 00:00:01 |

 

|*  2 |   INDEX RANGE SCAN          | TEMP_NAME_I |     2 |       |     1   (0)|

 00:00:01 |

 

--------------------------------------------------------------------------------

-----------

 

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   2 - access("NAME"='sony')

 

 

SQL>

创建反键索引

 

普通索引

SQL> create index temp_name on temp(name);

 

Index created.

 

SQL>

反键索引

SQL> create index temp_name_i on temp( reverse(name));

 

Index created.

 

SQL>

查找以a开头的走的是普通索引

SQL> select * from temp where name like 'A%';

 

Execution Plan

----------------------------------------------------------

Plan hash value: 953236590

 

--------------------------------------------------------------------------------

---------

 

| Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)| T

ime     |

 

--------------------------------------------------------------------------------

---------

 

|   0 | SELECT STATEMENT            |           |     1 |    38 |     0   (0)| 0

0:00:01 |

 

|   1 |  TABLE ACCESS BY INDEX ROWID| TEMP      |     1 |    38 |     0   (0)| 0

0:00:01 |

 

|*  2 |   INDEX RANGE SCAN          | TEMP_NAME |     1 |       |     0   (0)| 0

0:00:01 |

 

查找以什么结尾的会走索引全表扫描

SQL> select * from temp where name like '%Y';

 

Execution Plan

----------------------------------------------------------

Plan hash value: 3226310466

 

--------------------------------------------------------------------------------

---------

 

| Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)| T

ime     |

 

--------------------------------------------------------------------------------

---------

 

|   0 | SELECT STATEMENT            |           |     1 |    38 |     2   (0)| 0

0:00:01 |

 

|   1 |  TABLE ACCESS BY INDEX ROWID| TEMP      |     1 |    38 |     2   (0)| 0

0:00:01 |

 

|*  2 |   INDEX FULL SCAN           | TEMP_NAME |     1 |       |     1   (0)| 0

0:00:01 |

 

--------------------------------------------------------------------------------

---------

 

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   2 - filter("NAME" IS NOT NULL AND "NAME" LIKE '%Y')

 

 

SQL>

 

如果不想索引全表扫描那么可以使用反键

SQL> select * from temp where reverse(name) like 'Y%';

 

 

Execution Plan

----------------------------------------------------------

Plan hash value: 1257893614

 

--------------------------------------------------------------------------------

-----------

 

| Id  | Operation                   | Name        | Rows  | Bytes | Cost (%CPU)|

 Time     |

 

--------------------------------------------------------------------------------

-----------

 

|   0 | SELECT STATEMENT            |             |     1 |    38 |     2   (0)|

 00:00:01 |

 

|   1 |  TABLE ACCESS BY INDEX ROWID| TEMP        |     1 |    38 |     2   (0)|

 00:00:01 |

 

|*  2 |   INDEX RANGE SCAN          | TEMP_NAME_I |     1 |       |     1   (0)|

 00:00:01 |

 

--------------------------------------------------------------------------------

-----------

 

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   2 - access(REVERSE("NAME") LIKE 'Y%')

       filter(REVERSE("NAME") LIKE 'Y%')

 

 

SQL>

 

对于热点块就可以使用反键索引(将存储的值分散到不同的块中。)

 

将普通索引重建为反键索引

SQL>alter index temp1_sal_i rebuild reverse;

 

如果以前列中的值为 0001,0002,0003,0004… 这种连续的

那么使用反键索引就会将值变为1000,2000,3000,4000这种不连续的达到存储到不同块中的目的。

 

创建文本索引

 

 

SQL> conn / as sysdba

 

SQL> create table u1.test1 as select * from tab;

 

SQL> conn u1/u1

创建普通索引

SQL>create index test1_tname_i on test1(tname);

SQL>set autot trace exp

查询在tname列包含SEG的所有值 发现是不走索引的

SQL> select tname from test1 where tname like '%SEG%';

 

Execution Plan

----------------------------------------------------------

Plan hash value: 1751340739

 

--------------------------------------------------------------------------------

------

 

| Id  | Operation            | Name          | Rows  | Bytes | Cost (%CPU)| Time

     |

 

--------------------------------------------------------------------------------

------

 

|   0 | SELECT STATEMENT     |               |    25 |   425 |     6   (0)| 00:0

0:01 |

 

|*  1 |  INDEX FAST FULL SCAN| TEST1_TNAME_I |    25 |   425 |     6   (0)| 00:0

0:01 |

 

建立文本索引

SQL> drop index test1_tname_i;

 

SQL> create index test1_tname_i on test1(tname) indextype is ctxsys.context;

 

Index created.

 

SQL>

SQL> select tname from test1 where contains(tname, '%SEG%')>0;

 

Execution Plan

----------------------------------------------------------

Plan hash value: 2080224863

 

--------------------------------------------------------------------------------

-------------

 

| Id  | Operation                   | Name          | Rows  | Bytes | Cost (%CPU

)| Time     |

 

--------------------------------------------------------------------------------

-------------

 

|   0 | SELECT STATEMENT            |               |     2 |    58 |     4   (0

)| 00:00:01 |

 

|   1 |  TABLE ACCESS BY INDEX ROWID| TEST1         |     2 |    58 |     4   (0

)| 00:00:01 |

 

|*  2 |   DOMAIN INDEX              | TEST1_TNAME_I |       |       |     4   (0

)| 00:00:01 |

 

--------------------------------------------------------------------------------

-------------

 

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   2 - access("CTXSYS"."CONTAINS"("TNAME",'%SEG%')>0)

 

SQL>

 

创建函数索引

要使用函数索引必须保证sysdba用户以下值是正确的

 

SQL> conn / as sysdba

Connected.

SQL> show parameter que

 

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

db_unique_name                       string      fengzi

job_queue_processes                  integer     10

query_rewrite_enabled                string      TRUE   query_rewrite_enabled 参数为true

query_rewrite_integrity            string      enforced        query_rewrite_integrity数为enforced或者为truseted     函数索引就有效)                                                                                

SQL>

 

 

 

SQL> select * from temp where sal+nvl(comm,0)>4000;

 

        ID NAME                        SAL       COMM

---------- -------------------- ---------- ----------

      1568 lenovo                     1018       3000

      1788 lenovo                     1758       3100

 

SQL>

 

SQL> create index temp_sal_nvl on temp (sal+nvl(comm,0));

 

Index created.

 

SQL>

SQL> set autot trace exp

SQL> select * from temp where sal+nvl(comm,0)>4000;

 

Execution Plan

----------------------------------------------------------

Plan hash value: 2060561913

 

--------------------------------------------------------------------------------

------------

 

| Id  | Operation                   | Name         | Rows  | Bytes | Cost (%CPU)

| Time     |

 

--------------------------------------------------------------------------------

------------

 

|   0 | SELECT STATEMENT            |              |     2 |   102 |     2   (0)

| 00:00:01 |

 

|   1 |  TABLE ACCESS BY INDEX ROWID| TEMP         |     2 |   102 |     2   (0)

| 00:00:01 |

 

|*  2 |   INDEX RANGE SCAN          | TEMP_SAL_NVL |     1 |       |     1   (0)

| 00:00:01 |

 

--------------------------------------------------------------------------------

------------

 

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   2 - access("SAL"+NVL("COMM",0)>4000)

 

SQL>

 

如果数据库采用了加密技术如何实现以下语句走索引(采用加密技术的数据库不等式是不走索引的)

SQL> select * from temp where sal<2000;

SQL> select * from temp where sal between 2000 and 3000 ;

SQL> select * from temp where sal>3000;

可以自己定义函数创建函数索引

SQL> create or replace function gsal(vsal number)

  2  return number  deterministic

  3  as

  4  begin

  5  if vsal<2000 then return 1;

  6  elsif vsal between 2000 and 3000 then return 2;

  7  else return 3;

  8  end if;

  9  end gsal;

10  /

Function created.

 

SQL>

验证函数是否有效

SQL> select gsal(500) from dual;

 

 GSAL(500)

----------

         1

 

SQL> select gsal(2500) from dual;

 

GSAL(2500)

----------

         2

 

SQL> select gsal(3200) from dual;

 

GSAL(3200)

----------

         3

 

SQL>

创建函数索引

SQL> create index temp_sal_f on temp(gsal(sal));

 

Index created.

 

SQL>

查看执行计划

SQL> set autot trace exp

SQL> select * from temp where gsal(sal)=1;

 

Execution Plan

----------------------------------------------------------

Plan hash value: 1671644050

 

--------------------------------------------------------------------------------

----------

 

| Id  | Operation                   | Name       | Rows  | Bytes | Cost (%CPU)|

Time     |

 

--------------------------------------------------------------------------------

----------

 

|   0 | SELECT STATEMENT            |            |     1 |    51 |     2   (0)|

00:00:01 |

 

|   1 |  TABLE ACCESS BY INDEX ROWID| TEMP       |     1 |    51 |     2   (0)|

00:00:01 |

 

|*  2 |   INDEX RANGE SCAN          | TEMP_SAL_F |     1 |       |     1   (0)|

00:00:01 |

 

--------------------------------------------------------------------------------

----------

 

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   2 - access("U1"."GSAL"("SAL")=1)

 

创建空值索引

 

创建普通索引

SQL> create index temp_comm_i on temp(comm);

Index created.

SQL>

SQL> set autot trace exp

SQL> select * from temp where comm is null;

 

Execution Plan

----------------------------------------------------------

Plan hash value: 1896031711

 

--------------------------------------------------------------------------

| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |

--------------------------------------------------------------------------

|   0 | SELECT STATEMENT  |      |     4 |   204 |     3   (0)| 00:00:01 |

|*  1 |  TABLE ACCESS FULL| TEMP |     4 |   204 |     3   (0)| 00:00:01 |

--------------------------------------------------------------------------

 

创建空值索引

SQL> drop index temp_comm_i;

 

Index dropped.

 

SQL>

SQL> create index temp_comm_i on temp(sys_op_map_nonnull(comm));

 

Index created.

 

SQL> select * from temp where sys_op_map_nonnull(comm)=sys_op_map_nonnull(null);

 

Execution Plan

----------------------------------------------------------

Plan hash value: 285497915

 

--------------------------------------------------------------------------------

-----------

 

| Id  | Operation                   | Name        | Rows  | Bytes | Cost (%CPU)|

 Time     |

 

--------------------------------------------------------------------------------

-----------

 

|   0 | SELECT STATEMENT            |             |     1 |    51 |     2   (0)|

 00:00:01 |

 

|   1 |  TABLE ACCESS BY INDEX ROWID| TEMP        |     1 |    51 |     2   (0)|

 00:00:01 |

 

|*  2 |   INDEX RANGE SCAN          | TEMP_COMM_I |     1 |       |     1   (0)|

 00:00:01 |

 

--------------------------------------------------------------------------------

 

还可以创建组合索引,将有空值的列放在组合索引的前端。

创建隐藏索引

11g以前的版本是不能创建的。

 

SQL> conn scott/tiger

Connected.

SQL> select * from tab;

 

TNAME                          TABTYPE  CLUSTERID

------------------------------ ------- ----------

BONUS                          TABLE

DEPT                           TABLE

EMP                            TABLE

SALGRADE                       TABLE

 

SQL> create index emp_ename_i on emp(ename) invisible;

 

Index created.

 

SQL>

查看索引状态

SQL> select index_name,visibility from user_indexes;

 

INDEX_NAME                     VISIBILIT

------------------------------ ---------

PK_EMP                         VISIBLE

EMP_ENAME_I                    INVISIBLE

PK_DEPT                        VISIBLE

 

SQL>

查询一下执行计划看是否走索引

SQL> set autot trace exp

SQL> select * from emp where ename='KING';

 

Execution Plan

----------------------------------------------------------

Plan hash value: 3956160932

 

--------------------------------------------------------------------------

| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |

--------------------------------------------------------------------------

|   0 | SELECT STATEMENT  |      |     1 |    87 |     3   (0)| 00:00:01 |

|*  1 |  TABLE ACCESS FULL| EMP  |     1 |    87 |     3   (0)| 00:00:01 |

--------------------------------------------------------------------------

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   1 - filter("ENAME"='KING')

 

实现隐藏索引正常使用需要sysdba用户修改optimizer_use_invisible_indexes参数为true

SQL> conn / as sysdba    

Connected.

SQL> show parameter optim

 

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

object_cache_optimal_size            integer     102400

optimizer_capture_sql_plan_baselines boolean     FALSE

optimizer_dynamic_sampling           integer     2

optimizer_features_enable            string      11.2.0.2

optimizer_index_caching              integer     0

optimizer_index_cost_adj             integer     100

optimizer_mode                       string      ALL_ROWS

optimizer_secure_view_merging        boolean     TRUE

optimizer_use_invisible_indexes      boolean     FALSE

optimizer_use_pending_statistics     boolean     FALSE

optimizer_use_sql_plan_baselines     boolean     TRUE

 

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

plsql_optimize_level                 integer     2

SQL>

SQL> alter session set optimizer_use_invisible_indexes=true;

 

Session altered.

 

SQL> set autot trace exp

SQL> select * from scott.emp where ename='KING';

 

Execution Plan

----------------------------------------------------------

Plan hash value: 549418132

 

--------------------------------------------------------------------------------

-----------

 

| Id  | Operation                   | Name        | Rows  | Bytes | Cost (%CPU)|

 Time     |

 

--------------------------------------------------------------------------------

-----------

 

|   0 | SELECT STATEMENT            |             |     1 |    87 |     2   (0)|

 00:00:01 |

 

|   1 |  TABLE ACCESS BY INDEX ROWID| EMP         |     1 |    87 |     2   (0)|

 00:00:01 |

 

|*  2 |   INDEX RANGE SCAN          | EMP_ENAME_I |     1 |       |     1   (0)|

 00:00:01 |

 

--------------------------------------------------------------------------------

-----------

 

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   2 - access("ENAME"='KING')

 

 

SQL>

可以修改隐藏索引为正常索引

SQL> alter index scott.emp_ename_i visible;

 

Index altered.

 

SQL>

同样也可以修改正常索引为隐藏索引

SQL> alter index scott.emp_ename_i invisible;

 

Index altered.

 

SQL>

 

 

创建位图索引

 

创建普通索引

SQL> create index temp_name_i on temp(name);

 

Index created.

查看执行计划

SQL> set autot trace exp

SQL> select * from temp where name='sonny';

 

Execution Plan

----------------------------------------------------------

Plan hash value: 1257893614

 

--------------------------------------------------------------------------------

-----------

 

| Id  | Operation                   | Name        | Rows  | Bytes | Cost (%CPU)|

 Time     |

 

--------------------------------------------------------------------------------

-----------

 

|   0 | SELECT STATEMENT            |             |     4 |   204 |     2   (0)|

 00:00:01 |

 

|   1 |  TABLE ACCESS BY INDEX ROWID| TEMP        |     4 |   204 |     2   (0)|

 00:00:01 |

 

|*  2 |   INDEX RANGE SCAN          | TEMP_NAME_I |     4 |       |     1   (0)|

 00:00:01 |

 

--------------------------------------------------------------------------------

-----------

 

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   2 - access("NAME"='sonny')

 

 

创建位图索引

SQL> drop index temp_name_i;

 

Index dropped.

 

SQL> create bitmap index  temp_name_i on temp(name);

 

Index created.

 

SQL> select * from temp where name='sonny';

 

Execution Plan

----------------------------------------------------------

Plan hash value: 1986849256

 

--------------------------------------------------------------------------------

------------

 

| Id  | Operation                    | Name        | Rows  | Bytes | Cost (%CPU)

| Time     |

 

--------------------------------------------------------------------------------

------------

 

|   0 | SELECT STATEMENT             |             |     4 |   204 |     1   (0)

| 00:00:01 |

 

|   1 |  TABLE ACCESS BY INDEX ROWID | TEMP        |     4 |   204 |     1   (0)

| 00:00:01 |

 

|   2 |   BITMAP CONVERSION TO ROWIDS|             |       |       |

|          |

 

|*  3 |    BITMAP INDEX SINGLE VALUE | TEMP_NAME_I |       |       |

|          |

 

--------------------------------------------------------------------------------

------------

 

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   3 - access("NAME"='sonny')

 

Note

-----

   - dynamic sampling used for this statement

 

SQL>

 

如果发现不走索引可以强制让语句走索引

SQL> select /*+ index(temp,temp_name_i) */ * from temp where name='sonny';

 

Execution Plan

----------------------------------------------------------

Plan hash value: 1986849256

 

--------------------------------------------------------------------------------

------------

 

| Id  | Operation                    | Name        | Rows  | Bytes | Cost (%CPU)

| Time     |

 

--------------------------------------------------------------------------------

------------

 

|   0 | SELECT STATEMENT             |             |     4 |   204 |     1   (0)

| 00:00:01 |

 

|   1 |  TABLE ACCESS BY INDEX ROWID | TEMP        |     4 |   204 |     1   (0)

| 00:00:01 |

 

|   2 |   BITMAP CONVERSION TO ROWIDS|             |       |       |

|          |

 

|*  3 |    BITMAP INDEX SINGLE VALUE | TEMP_NAME_I |       |       |

|          |

 

--------------------------------------------------------------------------------

------------

 创建位图连接索引

 

SQL> set autot trace exp

SQL> select  count(*) from temp t,coty c where t.id=c.id and c.name='sonny';

 

Execution Plan

----------------------------------------------------------

Plan hash value: 570564326

 

--------------------------------------------------------------------------------

---------

 

| Id  | Operation                     | Name    | Rows  | Bytes | Cost (%CPU)| T

ime     |

 

--------------------------------------------------------------------------------

---------

 

|   0 | SELECT STATEMENT              |         |     1 |    38 |     4   (0)| 0

0:00:01 |

 

|   1 |  SORT AGGREGATE               |         |     1 |    38 |            |

        |

 

|   2 |   NESTED LOOPS                |         |     1 |    38 |     4   (0)| 0

0:00:01 |

 

|   3 |    TABLE ACCESS FULL          | TEMP    |     8 |   104 |     3   (0)| 0

0:00:01 |

 

|*  4 |    TABLE ACCESS BY INDEX ROWID| COTY    |     1 |    25 |     1   (0)| 0

0:00:01 |

 

|*  5 |     INDEX UNIQUE SCAN         | PK_COTY |     1 |       |     0   (0)| 0

0:00:01 |

 

--------------------------------------------------------------------------------

---------

 

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   4 - filter("C"."NAME"='sonny')

   5 - access("T"."ID"="C"."ID")

 

Note

-----

   - dynamic sampling used for this statement

 

SQL>

 

创建位图连接索引

SQL> create bitmap index temp_bit on temp(c.name) from temp t,coty c where t.id=c.id;

 

Index created.

 

SQL>

查看索引状态

SQL> select index_name,index_type from user_indexes;

 

INDEX_NAME                     INDEX_TYPE

------------------------------ ---------------------------

TEST1_TNAME_I                  DOMAIN

SYS_IOT_TOP_51560              IOT - TOP

SYS_IL0000051557C00002$$       LOB

SYS_IOT_TOP_51555              IOT - TOP

SYS_IL0000051552C00006$$       LOB

DR$TEST1_TNAME_I$X             NORMAL

TEMP_BIT                       BITMAP

SYS_C005242                    NORMAL

PK_COTY                        NORMAL

 

9 rows selected.

 

SQL>

查看执行计划

SQL> set autot trace exp

SQL> select  count(*) from temp t,coty c where t.id=c.id and c.name='sonny';

 

Execution Plan

----------------------------------------------------------

Plan hash value: 2037991701

 

--------------------------------------------------------------------------------

--------

 

| Id  | Operation                   | Name     | Rows  | Bytes | Cost (%CPU)| Ti

me     |

 

--------------------------------------------------------------------------------

--------

 

|   0 | SELECT STATEMENT            |          |     1 |    13 |     1   (0)| 00

:00:01 |

 

|   1 |  SORT AGGREGATE             |          |     1 |    13 |            |

       |

 

|   2 |   BITMAP CONVERSION COUNT   |          |     4 |    52 |     1   (0)| 00 (发现使用索引资源消耗大大减小)

:00:01 |

 

|*  3 |    BITMAP INDEX SINGLE VALUE| TEMP_BIT |       |       |            |

       |

 

--------------------------------------------------------------------------------

--------

创建虚拟索引

虚拟索引没有段 是不占用存储空间的

 

 

SQL> create index temp_name_i on temp(name) nosegment;

 

Index created.

 

SQL>

收集统计信息

 

SQL> exec dbms_stats.gather_table_stats('U1','TEMP',cascade=>true);

 

PL/SQL procedure successfully completed.

 

SQL>

查看统计信息

SQL> set autot trace exp

SQL> select  name from temp where name='sonny';

 

Execution Plan

----------------------------------------------------------

Plan hash value: 1896031711

 

--------------------------------------------------------------------------

| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |

--------------------------------------------------------------------------

|   0 | SELECT STATEMENT  |      |     4 |    24 |     3   (0)| 00:00:01 |

|*  1 |  TABLE ACCESS FULL| TEMP |     4 |    24 |     3   (0)| 00:00:01 |

--------------------------------------------------------------------------

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   1 - filter("NAME"='sonny')

 

SQL>

需要使用隐藏参数才可以正常使用

 

SQL> alter session set "_use_nosegment_indexes"=true;

 

Session altered.

 

SQL>

SQL> select * from temp where name='sonny';

 

Execution Plan

----------------------------------------------------------

Plan hash value: 1896031711

 

--------------------------------------------------------------------------

| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |

--------------------------------------------------------------------------

|   0 | SELECT STATEMENT  |               |     1 |    6 |     2   (0)| 00:00:01 |

|*  1 |  INDEX RANGE SCAN| TEMP_NAME_I  |    1|    6 |     2   (0)| 00:00:01 |

--------------------------------------------------------------------------

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   1 - filter("NAME"='sonny')

 

SQL>

建隐藏参数设为false虚拟索引就会无效

SQL> alter session set "_use_nosegment_indexes"=false;

 

Session altered.

 

SQL>

 

监控索引

 

首先要知道索引的名字

SQL> select index_name from user_indexes;

 

 

INDEX_NAME

------------------------------

TEST1_TNAME_I

SYS_IOT_TOP_51560

SYS_IL0000051557C00002$$

SYS_IOT_TOP_51555

SYS_IL0000051552C00006$$

DR$TEST1_TNAME_I$X

TEMP_NAME_I

SYS_C005242

PK_COTY

 

9 rows selected.

 

开启索引监控

SQL> alter index temp_name_i monitoring usage;

Index altered.

执行跟索引有关查询语句

SQL> select * from temp where name='sonny';

 

        ID NAME                        SAL       COMM

---------- -------------------- ---------- ----------

      1534 sonny                      1542

      1534 sonny                      1542

      1534 sonny                      1542

      1534 sonny                      1542

 

查询视图

SQL> select * from v$object_usage;

 

INDEX_NAME                     TABLE_NAME                     MON USE

------------------------------ ------------------------------ --- ---

START_MONITORING    END_MONITORING

------------------- -------------------

TEMP_NAME_I                    TEMP                           YES YES 

04/28/2014 14:33:57

 

关闭监控

SQL> alter index temp_name_i nomonitoring usage;

 

Index altered.

 

SQL>

 

 

索引重命名

 

 

SQL> alter index temp_name_i rename to temp_name_index;

 

Index altered.

 

SQL>

 

 

对于分区表的索引

全局索引只有一个根是一个段

 

 

查看分区表是根据那个列分的区

SQL> select name,column_name from user_part_key_columns;

 

  NAME             COLUMN_NAME

---------------------------------------------------------

EMPL               DEPTNO

SQL>

 

全局索引的创建

SQL> create index empl_deptno_i on empl(deptno);

 

SQL>

如果对这个分区进行修改,那么所有的索引都将无效

 

可以建立一个本地索引这样对分区修改时不会对索引有影响的

 

SQL> create index empl_deptno_ix on empl(deptno) local;

 

如果我添加一个分区

SQL> alter table empl add partition empl_p5 values(50);

只需要对新加分区重建索引

SQL> alter index empl_deptno_i rebuild partition empl_p5;

 

查找无效的对象

 

 

SQL> select object_name,object_type,status from dba_objects where owner='SCOTT' and status <> 'VALID';

 

no rows selected

 

SQL>

 

 

查找索引无效的

 

SQL> select index_name,status from dba_indexes where owner='SCOTT' and status='UNUSABLE';

 

no rows selected

 

SQL>

 

 

分区表无效索引

 

SQL> select index_name,status from dba_ind_partitions  where  status='UNUSABLE';

 

no rows selected

 

SQL>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值