文章归档

关于index_equal index_join index_combine

今天下午部门一个兄弟做了一个关于index_join与injdex_combine区别的测试,引发我的兴趣, 找到一段Jonathan lewis在论坛的回复,简单翻译了下,并针对同事提供的说明做了一点补充与测试..

补充:刚刚看到Jonathan Lewis还有另外一篇关于index Combine的文章

http://nixforums.org/about109312-Hints-difference-between-AND_EQUAL–INDEX_JOIN-and-INDEX_.html
AND_EQUAL:

Can operate on 2 to 5 non-unique, single-column indexes with an equality condition on the indexed values. For colX = const each index produces a list of rowids which are guaranteed to be in rowid order, hence pre-sorted and ready for a merge join. rowids that survive the join are used to access the table

and-equal支持操作2-5个非唯一单列索引,这些索引都有一个基于索引值的等值查询条件。 对于colX = “常量”, 每个索引都生成一个排好了顺序的rowid列表, 可以直接进行合并连接. 符合连接条件的rowid用来访问表取得结果数据..

Index_join

Can be used to join any two indexes – no restrictions on number of columns, uniqueness, or predicates. Used to derive results without visiting the table at all. Each index is used to supply a (sub)set of its columns plus the relevant rowids. Oracle then performs a hash join on the two sets of data – using the rowid as the join column. Any data surviving the data is the answer set. Having joined two indexes by hash join, it is possible for Oracle to join a third, and so on until all the required columns have been join into the final result set

index join可以连接任意两个索引(没有任何限制,如列数量,索引唯一性,以及谓词等),以实现完全不需要访问表就得到结果集的查询。每个索引都提供结果集的一个完整或部分列的集合以及对应的rowid。Oracle接着对这两个数据集进行散列连接-使用rowid作为连接条件。连接得到的结果就是所需的结果集。对Oracle来讲, 可以对两个索引做散列连接, 自然也可以对三个索引进行连接, 一直到所有出现在select list的列都已经取到,从而得到最后需要的结果集。

Index combine

Used for bitmap operators (although you can reference b-tree indexes in the hint to indicate to Oracle
that the index is a candidate for ‘rowid conversion to bitmap’).
Oracle acquires bitmaps from each index, and uses the AND, OR, NOT, or MERGE operators to produce
a result bit string that can then be converted into rowids for visiting the table.

index_combine 主要用来处理bitmap操作(虽然, 也可以在提示中引用B-Tree索引来强制Oracle将这个B-Tree索引作为
“rowid conversion to bitmap”的一个候选项). Oracle会获取每个索引的bitmap,并使用AND/OR/NOT/MERGE
等位图操作来生成一个可转换成rowid的位串, 以使用这些rowid来访问数据表.

根据Joanthan Lewis的这份说明, 我个人的理解是, index join只会处理能够返回完整结果集的查询, 而index combine支持这两类操作..

下面是相关的测试结果, 包含我同事提供的两个对比测试结果。
–这是我针对同事的理解做的测试..以验证index combine支持需要回表与不需要回表的操作,虽然在实际运行中这种情况可能出现的并不多

user@host>explain plan for
  2  select /*+INDEX_COMBINE(member MEMBER_MID_IND MEMBER_COMPANY_IND)*/count(*)
  3  from member
  4  where company like :1
and member_id like :2;  5  

Explained.

user@host>@?/rdbms/admin/utlxplp.sql

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 1195767410

---------------------------------------------------------------------------------------------------------------
| Id  | Operation                        | Name               | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                 |                    |     1 |    27 |       |  4007   (2)| 00:00:49 |
|   1 |  SORT AGGREGATE                  |                    |     1 |    27 |       |            |          |
|   2 |   BITMAP CONVERSION COUNT        |                    | 17647 |   465K|       |  4007   (2)| 00:00:49 |
|   3 |    BITMAP AND                    |                    |       |       |       |            |          |
|   4 |     BITMAP CONVERSION FROM ROWIDS|                    |       |       |       |            |          |
|   5 |      SORT ORDER BY               |                    |       |       |  6280K|            |          |
|*  6 |       INDEX RANGE SCAN           | MEMBER_MID_IND     |       |       |       |   244   (1)| 00:00:03 |
|   7 |     BITMAP CONVERSION FROM ROWIDS|                    |       |       |       |            |          |
|   8 |      SORT ORDER BY               |                    |       |       |  6280K|            |          |
|*  9 |       INDEX RANGE SCAN           | MEMBER_COMPANY_IND |       |       |       |   278   (1)| 00:00:04 |
---------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   6 - access("MEMBER_ID" LIKE :2)
       filter("MEMBER_ID" LIKE :2 AND "MEMBER_ID" LIKE :2)
   9 - access("COMPANY" LIKE :1)
       filter("COMPANY" LIKE :1 AND "COMPANY" LIKE :1)

24 rows selected.

–这一段是我的同事提供的测试代码..在此谢谢了…


--index hash join
select count(*)
from member
where company like :1
and member_id like :2;

------------------------------------------------------------------------------------------
| Id  | Operation           | Name               | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |                    |     1 |    27 |  1877   (1)| 00:00:23 |
|   1 |  SORT AGGREGATE     |                    |     1 |    27 |            |          |
|*  2 |   VIEW              | index$_join$_001   | 17647 |   465K|  1877   (1)| 00:00:23 |
|*  3 |    HASH JOIN        |                    |       |       |            |          |
|*  4 |     INDEX RANGE SCAN| MEMBER_MID_IND     | 17647 |   465K|  1970   (2)| 00:00:24 |
|*  5 |     INDEX RANGE SCAN| MEMBER_COMPANY_IND | 17647 |   465K|  2038   (2)| 00:00:25 |
------------------------------------------------------------------------------------------

--index combine
select *
from member
where company like :1
and member_id like :2;

---------------------------------------------------------------------------------------------------------------
| Id  | Operation                        | Name               | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                 |                    | 17647 |  5394K|       |  9135   (1)| 00:01:50 |
|   1 |  TABLE ACCESS BY INDEX ROWID     | MEMBER             | 17647 |  5394K|       |  9135   (1)| 00:01:50 |
|   2 |   BITMAP CONVERSION TO ROWIDS    |                    |       |       |       |            |          |
|   3 |    BITMAP AND                    |                    |       |       |       |            |          |
|   4 |     BITMAP CONVERSION FROM ROWIDS|                    |       |       |       |            |          |
|   5 |      SORT ORDER BY               |                    |       |       |  6280K|            |          |
|*  6 |       INDEX RANGE SCAN           | MEMBER_MID_IND     | 63530 |       |       |   244   (1)| 00:00:03 |
|   7 |     BITMAP CONVERSION FROM ROWIDS|                    |       |       |       |            |          |
|   8 |      SORT ORDER BY               |                    |       |       |  6280K|            |          |
|*  9 |       INDEX RANGE SCAN           | MEMBER_COMPANY_IND | 63530 |       |       |   278   (1)| 00:00:04 |
---------------------------------------------------------------------------------------------------------------

解释:
--index hash join: 将两个index range scan得到的rowid结果集进行hash join,用于不需要回表的情况。
--index bitmap combine: 将两个index range scan得到的rowid结果集进行bitmap and,用于需要回表的情况。

No related posts.

Leave a Reply

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>