ORACLE invisible index/virtual index(不可见/虚拟索引)
2012-09-13 19:28
579 查看
今天同事在优化的时候说到了虚拟索引这个东西,下面我们就来测试一下ORACLE数据的invisible与virtual索引,这两个索引对我们优化来说都有很大的好处。invisible索引在11G中才出现的,以前的版本中不可用。
invisible索引:当我们在生产环境中优化的时候,创建一个索引后,可能会影响到其它的SQL的执行效果,如果使用invisible索引,就不会影响到其它SQL语句的执行效果,因为它对其它是不可见,除非指定OPTIMIZER_USE_INVISIBLE_INDEXES这个参数为ture。invisible索引要占用空间,同时可以使用alter语句来对索引进行操作。
virtual索引:跟invisible一样,正常情况下不可用,除非指定_USE_NOSEGMENT_INDEXES参数为true。因为是虚拟的索引,所以创建他们不会分配空间,不能使用alter语句对它进行操作,可以对它进行分析。如果在一张几十G的表上创建一个virtual是很方面的。
下面就是关于invisible与virtual的测试。
测试环境是OS :RHEL 5.6 X*6_64 DB:11.2.0.3
1 invisible索引:
2 virtual索引
invisible/virtual索引就测试到这里。
invisible索引:当我们在生产环境中优化的时候,创建一个索引后,可能会影响到其它的SQL的执行效果,如果使用invisible索引,就不会影响到其它SQL语句的执行效果,因为它对其它是不可见,除非指定OPTIMIZER_USE_INVISIBLE_INDEXES这个参数为ture。invisible索引要占用空间,同时可以使用alter语句来对索引进行操作。
virtual索引:跟invisible一样,正常情况下不可用,除非指定_USE_NOSEGMENT_INDEXES参数为true。因为是虚拟的索引,所以创建他们不会分配空间,不能使用alter语句对它进行操作,可以对它进行分析。如果在一张几十G的表上创建一个virtual是很方面的。
下面就是关于invisible与virtual的测试。
测试环境是OS :RHEL 5.6 X*6_64 DB:11.2.0.3
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 virtual索引
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索引就测试到这里。
相关文章推荐
- Oracle 11g新特性invisible index(不可见的索引)
- 索引虚拟oracle virtual index
- Oracle 11g新特性invisible index(不可见的索引)
- ORACLE虚拟索引(Virtual Index)
- oracle 虚拟索引和不可见索引
- 【索引】Oracle之不可见索引和虚拟索引的比对
- Oracle笔记 之 索引(index)
- Oracle 唯一 约束(unique constraint) 与 索引(index) 关系说明
- oracle:索引操作,index
- 20180331:Oracle中的视图(view)、索引(index)、约束(constraint)、序列(sequence)
- Oracle_索引置为invisible和unusable状态是否占用空间
- Oracle11新特性——在线操作功能增强之新增的不可见索引
- Oracle index unusable和invisible的区别
- Oracle 唯一 约束(unique constraint) 与 索引(index) 关系说明
- Oracle 虚拟索引(Virtual index)
- oracle 索引index那些事
- Oracle笔记 之 索引(index)
- 创建virtual private catalog(虚拟用户目录)(oracle 11g) 步骤
- Oracle中查询时候使index索引失效的限制条件
- Oracle Study---Oracle 11g 不可见索引案例