今天同事在優化的時候說到了虛擬索引這個東西,下面咱們就來測試一下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索引就測試到這裏。優化