Oracle中常见的Hint(4)

scott@TEST>create index idx_emp_mgr on emp(mgr);
 
Index created.
 
scott@TEST>create index idx_emp_dept on emp(deptno);
 
Index created.
 
scott@TEST>select /*+ index_combine(emp pk_emp idx_emp_mgr idx_emp_deptno) */ empno,ename,sal,job
  2  from emp
  3  where empno=7369 and mgr=7902 and deptno=20;
 
    EMPNO ENAME              SAL JOB
---------- ------------------------------ ---------- ---------------------------
      7369 SMITH              800 CLERK
 
 
Execution Plan
----------------------------------------------------------
Plan hash value: 1816402415
 
-------------------------------------------------------------------------------------------------
| Id  | Operation            | Name  | Rows | Bytes | Cost (%CPU)| Time    |
-------------------------------------------------------------------------------------------------
|  0 | SELECT STATEMENT      |    |    1 |    29 |    2  (0)| 00:00:01 |
|  1 |  TABLE ACCESS BY INDEX ROWID  | EMP        |    1 |    29 |    2  (0)| 00:00:01 |
|  2 |  BITMAP CONVERSION TO ROWIDS  |    |  |  |        |    |
|  3 |    BITMAP AND          |    |  |  |        |    |
|  4 |    BITMAP CONVERSION FROM ROWIDS|      |  |  |        |    |
|*  5 |      INDEX RANGE SCAN        | PK_EMP |  |  |    0  (0)| 00:00:01 |
|  6 |    BITMAP CONVERSION FROM ROWIDS|      |  |  |        |    |
|*  7 |      INDEX RANGE SCAN        | IDX_EMP_MGR    |  |  |    1  (0)| 00:00:01 |
|  8 |    BITMAP CONVERSION FROM ROWIDS|      |  |  |        |    |
|*  9 |      INDEX RANGE SCAN        | IDX_EMP_DEPT |    |  |    1  (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------
......

从上面的执行计划中可以看到关键字“BITMAP CONVERSION FROM ROWIDS”、“BITMAP AND”和“BITMAP CONVERSION TO ROWIDS”,这说明Oracle先分别对上述三个单键值的B*Tree索引IDX_EMP_MGR、IDX_EMP_DEPT和PK_EMP用映射函数将其中的ROWID转换成了位图,然后对转换后的位图执行了BITMAP AND(位图按位与)布尔运算,最后将布尔运算的结果再次用映射函数转换成了ROWID并回表得到最终的执行结果。能走出这样的执行计划显然是因为INDEX_COMBINE Hint生效了。

用映射函数将ROWID转换成了位图,然后再执行布尔运算,最后将布尔运算的结果再次用映射函数转换成了ROWID并回表得到最终的执行结果,这个过程在实际生产环境中的执行效率可能是有问题的,可以使用隐含参数_B_TREE_BITMAP_PLANS禁掉该过程中的ROWID到位图的转换:

alter session set "_b_tree_bitmap_plans"=false;

scott@TEST>alter session set "_b_tree_bitmap_plans"=false;
 
Session altered.
 
scott@TEST>select /*+ index_combine(emp pk_emp idx_emp_mgr idx_emp_deptno) */ empno,ename,sal,job
  2    from emp
  3  where empno=7369 and mgr=7902 and deptno=20;
 
    EMPNO ENAME              SAL JOB
---------- ------------------------------ ---------- ---------------------------
      7369 SMITH              800 CLERK
 
 
Execution Plan
----------------------------------------------------------
Plan hash value: 2949544139
 
--------------------------------------------------------------------------------------
| Id  | Operation          | Name  | Rows  | Bytes | Cost (%CPU)| Time    |
--------------------------------------------------------------------------------------
|  0 | SELECT STATEMENT      |        |    1 |    29 |      1  (0)| 00:00:01 |
|*  1 |  TABLE ACCESS BY INDEX ROWID| EMP    |      1 |    29 |      1  (0)| 00:00:01 |
|*  2 |  INDEX UNIQUE SCAN    | PK_EMP |      1 |      |    0  (0)| 00:00:01 |
--------------------------------------------------------------------------------------
......

从上面的执行计划中可以看出没有出现BITMAP相关的关键字,即INDEX_COMBINE Hint被Oracle忽略了。

5、INDEX_FFS

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/96cde8cf0e53ab4350c556b7dfbc7aca.html