对于hints index() 的学习 (一)

对于hints index() 的学习 (一)

一、如何使用 /*+ index()*/   

The format for an index hint is:

 select /*+ index(TABLE_NAME INDEX_NAME) */ col1...

There are a number of rules that need to be applied to this hint:

1 The TABLE_NAME is mandatory in the hint
2 The table alias MUST be used if the table is aliased in the query
3 If TABLE_NAME or alias is spelled incorrectly then the hint will not be used.
4 The INDEX_NAME is optional. 
5 If an INDEX_NAME is entered without a TABLE_NAME then the hint will not be 
  applied.
6 If a TABLE_NAME is supplied on its own then the optimizer will decide 
  which index to use based on statistics.
7 If the INDEX_NAME is spelt incorrectly but the TABLE_NAME is spelled correctly 
  then the hint will not be applied even though the TABLE_NAME is correct.
8 If there are multiple index hints to be applied, then the simplest way of
  addressing this is to repeat the index hint syntax for each index e.g.:

     select /*+ index(TABLE_NAME1 INDEX_NAME1) index(TABLE_NAME2 INDEX_NAME2) */ col1...

9 Remember that the parser/optimizer may have transformed/rewritten the query
  or may have chosen an access path which make the use of the index invalid and
  this may result in the index not being used.

NB Please note that as long as the index() hint structure is correct
   it will force the use of the Cost Based Optimizer (CBO). This will happen
   even if the alias or table name is incorrect.

二、测试


 INDEX_NAME                     COLUMN_NAME
------------------------------ ----------------
IND_T1                             ENAME
II                                          EMPNO

SQL> select /*+index(t1) */empno from t1;

已选择12行。
执行计划
----------------------------------------------------------
Plan hash value: 3617692013
--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |    12 |    48 |     3   (0)| 00:00:01 |
|   1 |  TABLE ACCESS FULL| T1   |    12 |    48 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------

通过测试发现,此hints 没有起作用,但是也没有什么地方写错,最后加了一个主键后,走hints

SQL> select /*+ index(t1)*/t1.ename from T1;
已选择12行。
执行计划
----------------------------------------------------------
Plan hash value: 1552010074
------------------------------------------------------------------------------------
| Id  | Operation                   | Name | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |      |    12 |    72 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T1   |    12 |    72 |     2   (0)| 00:00:01 |
|   2 |   INDEX FULL SCAN           | II   |    12 |       |     1   (0)| 00:00:01 |
------------------------------------------------------------------------------------


下面我们逐一测试:

[sql] view plain copy
  1. 1、 index() 里的table_name 是强制性的提示,index_name是可选性的,如果 table_name 有别名,那么hints 中的表名也必须用别名  
  2. SQL> select /*+ index(t1)*/ ename from T1 a;  
  3.   
  4. 已选择12行。  
  5.   
  6.   
  7. 执行计划  
  8. ----------------------------------------------------------  
  9. Plan hash value: 3617692013  
  10.   
  11. --------------------------------------------------------------------------  
  12. | Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |  
  13. --------------------------------------------------------------------------  
  14. |   0 | SELECT STATEMENT  |      |    12 |    72 |     3   (0)| 00:00:01 |  
  15. |   1 |  TABLE ACCESS FULL| T1   |    12 |    72 |     3   (0)| 00:00:01 |  
  16. --------------------------------------------------------------------------  
  17.   
  18. 2、hints中 index()里的table_name 是必须的,但是index_name不是必须的,也就是说hints中只写index_name不写table_name,那么hints不会被使用  
  19. SQL> select /*+ index(ind_t1)*/ ename from T1 a;  
  20. 已选择12行。  
  21. 执行计划  
  22. ----------------------------------------------------------  
  23. Plan hash value: 3617692013  
  24.   
  25. --------------------------------------------------------------------------  
  26. | Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |  
  27. --------------------------------------------------------------------------  
  28. |   0 | SELECT STATEMENT  |      |    12 |    72 |     3   (0)| 00:00:01 |  
  29. |   1 |  TABLE ACCESS FULL| T1   |    12 |    72 |     3   (0)| 00:00:01 |  
  30. --------------------------------------------------------------------------  
  31. 3、如果hints中的table_name或者别名写的不正确,那么hints就不会被使用  
  32. SQL> select /*+ index(aa)*/ ename from T1 a;  
  33. 已选择12行。  
  34. 执行计划  
  35. ----------------------------------------------------------  
  36. Plan hash value: 3617692013  
  37.   
  38. --------------------------------------------------------------------------  
  39. | Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |  
  40. --------------------------------------------------------------------------  
  41. |   0 | SELECT STATEMENT  |      |    12 |    72 |     3   (0)| 00:00:01 |  
  42. |   1 |  TABLE ACCESS FULL| T1   |    12 |    72 |     3   (0)| 00:00:01 |  
  43. --------------------------------------------------------------------------  
  44.   
  45. SQL> select /*+ index(a ii_t1)*/ ename from T1 a;  
  46.   
  47. 已选择12行。  
  48.   
  49.   
  50. 执行计划  
  51. ----------------------------------------------------------  
  52. Plan hash value: 3617692013  
  53.   
  54. --------------------------------------------------------------------------  
  55. | Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |  
  56. --------------------------------------------------------------------------  
  57. |   0 | SELECT STATEMENT  |      |    12 |    72 |     3   (0)| 00:00:01 |  
  58. |   1 |  TABLE ACCESS FULL| T1   |    12 |    72 |     3   (0)| 00:00:01 |  
  59. --------------------------------------------------------------------------  
  60.   
  61.   
  62. 4、如果hints中写了table_name不写索引名,那么优化器会根据统计信息选择索引  
  63. QL> select /*+ index(a)*/ ename from T1 a;  
  64. 已选择12行。  
  65.   
  66. 执行计划  
  67. ---------------------------------------------------------  
  68. lan hash value: 1552010074  
  69.   
  70. -----------------------------------------------------------------------------------  
  71.  Id  | Operation                   | Name | Rows  | Bytes | Cost (%CPU)| Time     |  
  72. -----------------------------------------------------------------------------------  
  73.    0 | SELECT STATEMENT            |      |    12 |    72 |     2   (0)| 00:00:01 |  
  74.    1 |  TABLE ACCESS BY INDEX ROWID| T1   |    12 |    72 |     2   (0)| 00:00:01 |  
  75.    2 |   INDEX FULL SCAN           | II   |    12 |       |     1   (0)| 00:00:01 |  
  76. -----------------------------------------------------------------------------------  
  77.   
  78. 5、如果hints中的table_name 写错,而索引写正确 ,那么hints就不会被使用  
  79. SQL> select /*+ index(aa ii )*/ ename from T1 a;  
  80. 已选择12行。  
  81. 执行计划  
  82. ----------------------------------------------------------  
  83. Plan hash value: 3617692013  
  84.   
  85. --------------------------------------------------------------------------  
  86. | Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |  
  87. --------------------------------------------------------------------------  
  88. |   0 | SELECT STATEMENT  |      |    12 |    72 |     3   (0)| 00:00:01 |  
  89. |   1 |  TABLE ACCESS FULL| T1   |    12 |    72 |     3   (0)| 00:00:01 |  
  90. --------------------------------------------------------------------------  
  91.   
  92. 7、如果有多个索引要使用那么可以使用  /*+ index(TABLE_NAME1 INDEX_NAME1) index(TABLE_NAME2 INDEX_NAME2) */

你可能感兴趣的:(对于hints index() 的学习 (一))