Oracle执行计划中的and_equal

and_equal是Oracle支持的一种特定操作,可以将多个单列索引进行合并(Index Merge)输出查询结果。
同时and_equal可以通过Hints来进行强制,最少指定两个索引,最多指定5个。
以下的执行计划是常见的and_equal执行方式:
SQL> select /*+ and_equal(t1 iu ii) */  username,password from t1 where username='EYGLE' and user_id=58;
USERNAME                       PASSWORD
------------------------------ ------------------------------
EYGLE                          B726E09FE21F8E83

执行计划
----------------------------------------------------------
Plan hash value: 1425017857
------------------------------------------------------------------------------------
| Id  | Operation                   | Name | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |      |     1 |    47 |     2   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS BY INDEX ROWID| T1   |     1 |    47 |     2   (0)| 00:00:01 |
|   2 |   AND-EQUAL                 |      |       |       |            |          |
|*  3 |    INDEX RANGE SCAN         | II   |     1 |       |     1   (0)| 00:00:01 |
|*  4 |    INDEX RANGE SCAN         | IU   |     1 |       |     1   (0)| 00:00:01 |
------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter("USERNAME"='EYGLE' AND "USER_ID"=58)
   3 - access("USER_ID"=58)
   4 - access("USERNAME"='EYGLE')
但是从Oracle 10g开始,and_equal操作被废弃(depricated)掉,Oracle不再支持。这里废弃的含义并不是被彻底移除,而是说不再进行改进,通过hints仍然可以强制实现Index Merge的and_equal操作。
以上的输出就是来自Oracle 10.2.0.4,在使用rule提示时,Oracle会主动选择and_equal,所以不再支持是因为,这种方法限制过多,而且远不如复合索引来的灵活:
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Prod
PL/SQL Release 10.2.0.4.0 - Production
CORE    10.2.0.4.0      Production
TNS for 32-bit Windows: Version 10.2.0.4.0 - Production
NLSRTL Version 10.2.0.4.0 - Production

SQL> select /*+ rule */  username,password from t1 where username='EYGLE' and user_id=58;
USERNAME                       PASSWORD
------------------------------ ------------------------------
EYGLE                          B726E09FE21F8E83

执行计划
----------------------------------------------------------
Plan hash value: 3072843751
--------------------------------------------
| Id  | Operation                   | Name |
--------------------------------------------
|   0 | SELECT STATEMENT            |      |
|   1 |  TABLE ACCESS BY INDEX ROWID| T1   |
|   2 |   AND-EQUAL                 |      |
|*  3 |    INDEX RANGE SCAN         | IU   |
|*  4 |    INDEX RANGE SCAN         | II   |
--------------------------------------------
新的可选替代方案是NDEX_COMBINE,从9i开始,初始化参数 _b_tree_bitmap_plans设置为true,允许为B*Tree索引使用,bitmap convert:
SQL> select /*+ index_combine(t1 iu ii) */  username,password from t1 where username='EYGLE' and user_id=58;
USERNAME                       PASSWORD
------------------------------ ------------------------------
EYGLE                          B726E09FE21F8E83

执行计划
----------------------------------------------------------
Plan hash value: 1808973554
-----------------------------------------------------------------------------------------
| Id  | Operation                        | Name | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                 |      |     1 |    47 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID     | T1   |     1 |    47 |     2   (0)| 00:00:01 |
|   2 |   BITMAP CONVERSION TO ROWIDS    |      |       |       |            |          |
|   3 |    BITMAP AND                    |      |       |       |            |          |
|   4 |     BITMAP CONVERSION FROM ROWIDS|      |       |       |            |          |
|*  5 |      INDEX RANGE SCAN            | II   |       |       |     1   (0)| 00:00:01 |
|   6 |     BITMAP CONVERSION FROM ROWIDS|      |       |       |            |          |
|*  7 |      INDEX RANGE SCAN            | IU   |       |       |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   5 - access("USER_ID"=58)
   7 - access("USERNAME"='EYGLE')

标签: 暂无标签
oraunix

写了 199 篇文章,拥有财富 1026,被 339 人关注

转播转播 分享分享 分享淘帖
回复

使用道具

成为第一个吐槽的人

您需要登录后才可以回帖 登录 | 加入社区

本版积分规则

意见
反馈