ORACLE invisible index/virtual index(不可見/虛擬索引)

     今天同事在優化的時候說到了虛擬索引這個東西,下面咱們就來測試一下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.1 建立invisible索引,建立方法跟其它索引差很少,只是在最後增長invisible就能夠了。 
  2. SQL> create index scott.pk_test_owner on scott.test(owner) invisible; 
  3.  
  4. Index created. 
  5. 1.2 執行測試語句 
  6. SQL> select count(*) from scott.test where owner='SCOTT'
  7.  
  8.   COUNT(*) 
  9. ---------- 
  10.          9 
  11. 1.3 查看執行計劃 
  12. 這裏就是select * from table(dbms_xplan.display_cursor(null,null,all))這個語句 
  13. SQL> @/home/oracle/rs/sql/plan.sql 
  14.  
  15. PLAN_TABLE_OUTPUT 
  16. ---------------------------------------------------------------------------------------------------- 
  17. SQL_ID  248pfx54z79v4, child number 0 
  18. ------------------------------------- 
  19. select count(*) from scott.test where owner='SCOTT' 
  20.  
  21. Plan hash value: 1950795681 
  22.  
  23. --------------------------------------------------------------------------- 
  24. | Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     | 
  25. --------------------------------------------------------------------------- 
  26. |   0 | SELECT STATEMENT   |      |       |       |   297 (100)|          | 
  27. |   1 |  SORT AGGREGATE    |      |     1 |    17 |            |          | 
  28. |*  2 |   TABLE ACCESS FULL| TEST |    12 |   204 |   297   (1)| 00:00:04 | 
  29. --------------------------------------------------------------------------- 
  30. #這裏咱們看到了走的是全面掃描 
  31. Query Block Name / Object Alias (identified by operation id): 
  32. ------------------------------------------------------------- 
  33.  
  34.    1 - SEL$1 
  35.    2 - SEL$1 / TEST@SEL$1 
  36.  
  37. Predicate Information (identified by operation id): 
  38. --------------------------------------------------- 
  39.  
  40.    2 - filter("OWNER"='SCOTT'
  41.  
  42. Column Projection Information (identified by operation id): 
  43. ----------------------------------------------------------- 
  44.  
  45.    1 - (#keys=0) COUNT(*)[22] 
  46.  
  47. Note 
  48. ----- 
  49.    - dynamic sampling used for this statement (level=2) 
  50.  
  51.  
  52. 34 rows selected. 
  53. 1.4 設置參數爲true 
  54. SQL> alter session set OPTIMIZER_USE_INVISIBLE_INDEXES=true
  55.  
  56. Session altered. 
  57.  
  58.  
  59. 1.4 執行SQL 
  60. SQL> select count(*) from scott.test where owner='SCOTT'
  61.  
  62.   COUNT(*) 
  63. ---------- 
  64.          9 
  65. 1.6 查看執行計劃 
  66. SQL> @/home/oracle/rs/sql/plan 
  67.  
  68. PLAN_TABLE_OUTPUT 
  69. ---------------------------------------------------------------------------------------------------- 
  70. SQL_ID  248pfx54z79v4, child number 1 
  71. ------------------------------------- 
  72. select count(*) from scott.test where owner='SCOTT' 
  73.  
  74. Plan hash value: 4000037813 
  75.  
  76. ----------------------------------------------------------------------------------- 
  77. | Id  | Operation         | Name          | Rows  | Bytes | Cost (%CPU)| Time     | 
  78. ----------------------------------------------------------------------------------- 
  79. |   0 | SELECT STATEMENT  |               |       |       |     1 (100)|          | 
  80. |   1 |  SORT AGGREGATE   |               |     1 |    17 |            |          | 
  81. |*  2 |   INDEX RANGE SCAN| PK_TEST_OWNER |     9 |   153 |     1   (0)| 00:00:01 | 
  82. ----------------------------------------------------------------------------------- 
  83. #注意這裏已經走的是index range scan掃描了,已經達到效果了 
  84. Query Block Name / Object Alias (identified by operation id): 
  85. ------------------------------------------------------------- 
  86.  
  87.    1 - SEL$1 
  88.    2 - SEL$1 / TEST@SEL$1 
  89.  
  90. Predicate Information (identified by operation id): 
  91. --------------------------------------------------- 
  92.  
  93.    2 - access("OWNER"='SCOTT'
  94.  
  95. Column Projection Information (identified by operation id): 
  96. ----------------------------------------------------------- 
  97.  
  98.    1 - (#keys=0) COUNT(*)[22] 
  99.  
  100. Note 
  101. ----- 
  102.    - dynamic sampling used for this statement (level=2) 
  103.  
  104.  
  105. 34 rows selected. 
  106.  
  107. 1.7 查看索引的類型 
  108. SQL> select index_name,visibility from dba_indexes where owner='SCOTT' and table_name='TEST'
  109.  
  110. INDEX_NAME                     VISIBILIT 
  111. ------------------------------ --------- 
  112. PK_TEST_OWNER                  INVISIBLE 
  113. 1.8 查看索引佔用的空間大小 
  114. SQL> col segment_name for a20 
  115. SQL> select segment_name,sum(bytes/1024/1024)||'M' from dba_extents where segment_name='PK_TEST_OWNER'  group by segment_name; 
  116.  
  117. SEGMENT_NAME         SUM(BYTES/1024/1024)||'M' 
  118. -------------------- ----------------------------------------- 
  119. PK_TEST_OWNER        2M 
  120. 1.9 重建索引 
  121. SQL> alter index scott.pk_test_owner rebuild; 
  122.  
  123. Index altered. 
  124. SQL> select index_name,visibility from dba_indexes where owner='SCOTT' and table_name='TEST'
  125.  
  126. INDEX_NAME                     VISIBILIT 
  127. ------------------------------ --------- 
  128. PK_TEST_OWNER                  INVISIBLE 
  129. 1.10 invisible/visible轉化 
  130. 咱們能夠經過alter語句把對invisible/visible進行相互的轉換 
  131. SQL> alter index scott.pk_test_owner visible; 
  132.  
  133. Index altered. 
  134.  
  135. SQL> select index_name,visibility from dba_indexes where owner='SCOTT' and table_name='TEST'
  136.  
  137. INDEX_NAME                     VISIBILIT 
  138. ------------------------------ --------- 
  139. PK_TEST_OWNER                  VISIBLE 
2 virtual索引
  
  
  
  
  1. 2.1 建立一個virutal索引,就是在普通建立索引的方法後面增長一個nosegment就能夠。 
  2. SQL> create index scott.pk_test_objectname on scott.test(object_name) nosegment; 
  3.  
  4. Index created. 
  5. 2.2 執行測試語句,並查看執行計劃 
  6. SQL> select count(*) from scott.test where object_name='TEST'
  7.  
  8.  
  9. Execution Plan 
  10. ---------------------------------------------------------- 
  11. Plan hash value: 1950795681 
  12.  
  13. --------------------------------------------------------------------------- 
  14. | Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     | 
  15. --------------------------------------------------------------------------- 
  16. |   0 | SELECT STATEMENT   |      |     1 |    66 |   297   (1)| 00:00:04 | 
  17. |   1 |  SORT AGGREGATE    |      |     1 |    66 |            |          | 
  18. |*  2 |   TABLE ACCESS FULL| TEST |    12 |   792 |   297   (1)| 00:00:04 | 
  19. --------------------------------------------------------------------------- 
  20. #注意這裏走的全表掃描 
  21. Predicate Information (identified by operation id): 
  22. --------------------------------------------------- 
  23.  
  24.    2 - filter("OBJECT_NAME"='TEST'
  25.  
  26. Note 
  27. ----- 
  28.    - dynamic sampling used for this statement (level=2) 
  29.  
  30.  
  31. Statistics 
  32. ---------------------------------------------------------- 
  33.           5  recursive calls 
  34.           0  db block gets 
  35.        1134  consistent gets 
  36.        1061  physical reads 
  37.           0  redo size 
  38.         526  bytes sent via SQL*Net to client 
  39.         523  bytes received via SQL*Net from client 
  40.           2  SQL*Net roundtrips to/from client 
  41.           0  sorts (memory) 
  42.           0  sorts (disk) 
  43.           1  rows processed 
  44.  2.3 設置參數爲true          
  45. SQL>  alter session set "_USE_NOSEGMENT_INDEXES" = true
  46.  
  47. Session altered. 
  48. 2.4 執行測試語句,並查看執行計劃 
  49. SQL> select count(*) from scott.test where object_name='TEST'
  50.  
  51.  
  52. Execution Plan 
  53. ---------------------------------------------------------- 
  54. Plan hash value: 2753868186 
  55.  
  56. ---------------------------------------------------------------------------------------- 
  57. | Id  | Operation         | Name               | Rows  | Bytes | Cost (%CPU)| Time     | 
  58. ---------------------------------------------------------------------------------------- 
  59. |   0 | SELECT STATEMENT  |                    |     1 |    66 |     1   (0)| 00:00:01 | 
  60. |   1 |  SORT AGGREGATE   |                    |     1 |    66 |            |          | 
  61. |*  2 |   INDEX RANGE SCAN| PK_TEST_OBJECTNAME |    12 |   792 |     1   (0)| 00:00:01 | 
  62. ---------------------------------------------------------------------------------------- 
  63. #已經走了索引了,達到了效果 
  64. Predicate Information (identified by operation id): 
  65. --------------------------------------------------- 
  66.  
  67.    2 - access("OBJECT_NAME"='TEST'
  68.  
  69. Note 
  70. ----- 
  71.    - dynamic sampling used for this statement (level=2) 
  72.  
  73.  
  74. Statistics 
  75. ---------------------------------------------------------- 
  76.           0  recursive calls 
  77.           0  db block gets 
  78.        1064  consistent gets 
  79.        1061  physical reads 
  80.           0  redo size 
  81.         526  bytes sent via SQL*Net to client 
  82.         523  bytes received via SQL*Net from client 
  83.           2  SQL*Net roundtrips to/from client 
  84.           0  sorts (memory) 
  85.           0  sorts (disk) 
  86.           1  rows processed 
  87. SQL> select table_name,index_name from dba_indexes where owner='SCOTT' and table_name='TEST'
  88.  
  89. TABLE_NAME                     INDEX_NAME 
  90. ------------------------------ ------------------------------ 
  91. TEST                           PK_TEST_OWNER 
  92. 2.5 查看索引是否分配了segment,這裏爲0,因此沒有分配segment,不佔用空間的。 
  93. SQL> select count(*) from dba_segments where segment_name='PK_TEST_OBJECTNAME'
  94.  
  95.   COUNT(*) 
  96. ---------- 
  97.          0 
  98. 2.6 測試是否能夠用alterindex進行操做 
  99. SQL> alter index PK_TEST_OBJECTNAME rebuild; 
  100. alter index PK_TEST_OBJECTNAME rebuild 
  101. ERROR at line 1: 
  102. ORA-01418: specified index does not exist 

invisible/virtual索引就測試到這裏。優化

相關文章
相關標籤/搜索