今天同事在优化的时候说到了虚拟索引这个东西,下面咱们就来测试一下ORACLE数据的invisible与virtual索引,这两个索引对咱们优化来讲都有很大的好处。invisible索引在11G中才出现的,之前的版本中不可用。sql
invisible索引:当咱们在生产环境中优化的时候,建立一个索引后,可能会影响到其它的SQL的执行效果,若是使用invisible索引,就不会影响到其它SQL语句的执行效果,由于它对其它是不可见,除非指定OPTIMIZER_USE_INVISIBLE_INDEXES这个参数为ture。invisible索引要占用空间,同时能够使用alter语句来对索引进行操做。session
virtual索引:跟invisible同样,正常状况下不可用,除非指定_USE_NOSEGMENT_INDEXES参数为true。由于是虚拟的索引,因此建立他们不会分配空间,不能使用alter语句对它进行操做,能够对它进行分析。若是在一张几十G的表上建立一个virtual是很方面的。oracle
下面就是关于invisible与virtual的测试。app
测试环境是OS :RHEL 5.6 X*6_64 DB:11.2.0.3ide
1 invisible索引:测试
- 1.1 建立invisible索引,建立方法跟其它索引差很少,只是在最后增长invisible就能够了。
- SQL> create index scott.pk_test_owner on scott.test(owner) invisible;
- Index created.
- 1.2 执行测试语句
- SQL> select count(*) from scott.test where owner='SCOTT';
- COUNT(*)
- ----------
- 9
- 1.3 查看执行计划
- 这里就是select * from table(dbms_xplan.display_cursor(null,null,all))这个语句
- SQL> @/home/oracle/rs/sql/plan.sql
- PLAN_TABLE_OUTPUT
- ----------------------------------------------------------------------------------------------------
- SQL_ID 248pfx54z79v4, child number 0
- -------------------------------------
- select count(*) from scott.test where owner='SCOTT'
- Plan hash value: 1950795681
- ---------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
- ---------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | | | 297 (100)| |
- | 1 | SORT AGGREGATE | | 1 | 17 | | |
- |* 2 | TABLE ACCESS FULL| TEST | 12 | 204 | 297 (1)| 00:00:04 |
- ---------------------------------------------------------------------------
- #这里咱们看到了走的是全面扫描
- Query Block Name / Object Alias (identified by operation id):
- -------------------------------------------------------------
- 1 - SEL$1
- 2 - SEL$1 / TEST@SEL$1
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 2 - filter("OWNER"='SCOTT')
- Column Projection Information (identified by operation id):
- -----------------------------------------------------------
- 1 - (#keys=0) COUNT(*)[22]
- Note
- -----
- - dynamic sampling used for this statement (level=2)
- 34 rows selected.
- 1.4 设置参数为true
- SQL> alter session set OPTIMIZER_USE_INVISIBLE_INDEXES=true;
- Session altered.
- 1.4 执行SQL
- SQL> select count(*) from scott.test where owner='SCOTT';
- COUNT(*)
- ----------
- 9
- 1.6 查看执行计划
- SQL> @/home/oracle/rs/sql/plan
- PLAN_TABLE_OUTPUT
- ----------------------------------------------------------------------------------------------------
- SQL_ID 248pfx54z79v4, child number 1
- -------------------------------------
- select count(*) from scott.test where owner='SCOTT'
- Plan hash value: 4000037813
- -----------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
- -----------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | | | 1 (100)| |
- | 1 | SORT AGGREGATE | | 1 | 17 | | |
- |* 2 | INDEX RANGE SCAN| PK_TEST_OWNER | 9 | 153 | 1 (0)| 00:00:01 |
- -----------------------------------------------------------------------------------
- #注意这里已经走的是index range scan扫描了,已经达到效果了
- Query Block Name / Object Alias (identified by operation id):
- -------------------------------------------------------------
- 1 - SEL$1
- 2 - SEL$1 / TEST@SEL$1
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 2 - access("OWNER"='SCOTT')
- Column Projection Information (identified by operation id):
- -----------------------------------------------------------
- 1 - (#keys=0) COUNT(*)[22]
- Note
- -----
- - dynamic sampling used for this statement (level=2)
- 34 rows selected.
- 1.7 查看索引的类型
- SQL> select index_name,visibility from dba_indexes where owner='SCOTT' and table_name='TEST';
- INDEX_NAME VISIBILIT
- ------------------------------ ---------
- PK_TEST_OWNER INVISIBLE
- 1.8 查看索引占用的空间大小
- SQL> col segment_name for a20
- SQL> select segment_name,sum(bytes/1024/1024)||'M' from dba_extents where segment_name='PK_TEST_OWNER' group by segment_name;
- SEGMENT_NAME SUM(BYTES/1024/1024)||'M'
- -------------------- -----------------------------------------
- PK_TEST_OWNER 2M
- 1.9 重建索引
- SQL> alter index scott.pk_test_owner rebuild;
- Index altered.
- SQL> select index_name,visibility from dba_indexes where owner='SCOTT' and table_name='TEST';
- INDEX_NAME VISIBILIT
- ------------------------------ ---------
- PK_TEST_OWNER INVISIBLE
- 1.10 invisible/visible转化
- 咱们能够经过alter语句把对invisible/visible进行相互的转换
- SQL> alter index scott.pk_test_owner visible;
- Index altered.
- SQL> select index_name,visibility from dba_indexes where owner='SCOTT' and table_name='TEST';
- INDEX_NAME VISIBILIT
- ------------------------------ ---------
- PK_TEST_OWNER VISIBLE
- 2.1 建立一个virutal索引,就是在普通建立索引的方法后面增长一个nosegment就能够。
- SQL> create index scott.pk_test_objectname on scott.test(object_name) nosegment;
- Index created.
- 2.2 执行测试语句,并查看执行计划
- SQL> select count(*) from scott.test where object_name='TEST';
- Execution Plan
- ----------------------------------------------------------
- Plan hash value: 1950795681
- ---------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
- ---------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 1 | 66 | 297 (1)| 00:00:04 |
- | 1 | SORT AGGREGATE | | 1 | 66 | | |
- |* 2 | TABLE ACCESS FULL| TEST | 12 | 792 | 297 (1)| 00:00:04 |
- ---------------------------------------------------------------------------
- #注意这里走的全表扫描
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 2 - filter("OBJECT_NAME"='TEST')
- Note
- -----
- - dynamic sampling used for this statement (level=2)
- Statistics
- ----------------------------------------------------------
- 5 recursive calls
- 0 db block gets
- 1134 consistent gets
- 1061 physical reads
- 0 redo size
- 526 bytes sent via SQL*Net to client
- 523 bytes received via SQL*Net from client
- 2 SQL*Net roundtrips to/from client
- 0 sorts (memory)
- 0 sorts (disk)
- 1 rows processed
- 2.3 设置参数为true
- SQL> alter session set "_USE_NOSEGMENT_INDEXES" = true;
- Session altered.
- 2.4 执行测试语句,并查看执行计划
- SQL> select count(*) from scott.test where object_name='TEST';
- Execution Plan
- ----------------------------------------------------------
- Plan hash value: 2753868186
- ----------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
- ----------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 1 | 66 | 1 (0)| 00:00:01 |
- | 1 | SORT AGGREGATE | | 1 | 66 | | |
- |* 2 | INDEX RANGE SCAN| PK_TEST_OBJECTNAME | 12 | 792 | 1 (0)| 00:00:01 |
- ----------------------------------------------------------------------------------------
- #已经走了索引了,达到了效果
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 2 - access("OBJECT_NAME"='TEST')
- Note
- -----
- - dynamic sampling used for this statement (level=2)
- Statistics
- ----------------------------------------------------------
- 0 recursive calls
- 0 db block gets
- 1064 consistent gets
- 1061 physical reads
- 0 redo size
- 526 bytes sent via SQL*Net to client
- 523 bytes received via SQL*Net from client
- 2 SQL*Net roundtrips to/from client
- 0 sorts (memory)
- 0 sorts (disk)
- 1 rows processed
- SQL> select table_name,index_name from dba_indexes where owner='SCOTT' and table_name='TEST';
- TABLE_NAME INDEX_NAME
- ------------------------------ ------------------------------
- TEST PK_TEST_OWNER
- 2.5 查看索引是否分配了segment,这里为0,因此没有分配segment,不占用空间的。
- SQL> select count(*) from dba_segments where segment_name='PK_TEST_OBJECTNAME';
- COUNT(*)
- ----------
- 0
- 2.6 测试是否能够用alter对index进行操做
- SQL> alter index PK_TEST_OBJECTNAME rebuild;
- alter index PK_TEST_OBJECTNAME rebuild
- *
- ERROR at line 1:
- ORA-01418: specified index does not exist
invisible/virtual索引就测试到这里。优化