INLIST ITERATOR与CONCATENATION区别

INLIST ITERATOR :迭代查询,lnlist 里面几个值就要扫描几次。
CONCATENATION :联合返回二个或多个行集。

官方文档:
When the Optimizer Uses IN-List Iterators  The optimizer uses an IN-list iterator when an IN clause is specified with values, and the optimizer finds a selective index  for that column. If there are multiple OR clauses using the same index, then the optimizer chooses this operation  rather than CONCATENATION or UNION ALL, because it is more efficient.
翻译大致的意思是,如果用的or条件使用了相同的索引,优化器会更趋向于选择IN-list iterator,而不是CONCATENATION或UNION ALL。

iterator里面每次执行的代码都一样只是变量值不同,CONCATENATION里面的代码可能不同(比如 A=0 OR B=0)只是最终结果可以合并。

----------------------------------------------------------开始试验--------------------------------------------------------------

create table test as select * from dba_objects;
create index I_OBJECT_ID on TEST (OBJECT_ID);
create index I_OBJECT_NAME on TEST (OBJECT_NAME);

SQL> select /*+gather_plan_statistics*/ count(1) from test where
  2  object_id in(20,30,40,50,60);
  COUNT(1)
----------
         5
SQL> SELECT * FROM table(dbms_xplan.display_cursor(null,null,'iostats last'));
--------------------------------------------------------------------------------------------
| Id  | Operation          | Name        | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
--------------------------------------------------------------------------------------------
|   1 |  SORT AGGREGATE    |             |      1 |      1 |      1 |00:00:00.01 |      10 |
|   2 |   INLIST ITERATOR  |             |      1 |        |      5 |00:00:00.01 |      10 |
|*  3 |    INDEX RANGE SCAN| I_OBJECT_ID |      5 |      5 |      5 |00:00:00.01 |      10 | ---有几个值就迭代几次
--------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   3 - access(("OBJECT_ID"=20 OR "OBJECT_ID"=30 OR "OBJECT_ID"=40 OR "OBJECT_ID"=50
              OR "OBJECT_ID"=60))


SQL> select /*+gather_plan_statistics*/ count(1) from test a
  2      where a.object_id=20 or a.object_name='ICOL$';
  COUNT(1)
----------
         1
SQL> SELECT * FROM table(dbms_xplan.display_cursor(null,null,'iostats last'));
------------------------------------------------------------------------------------------------------------
| Id  | Operation                        | Name          | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
------------------------------------------------------------------------------------------------------------

|   1 |  SORT AGGREGATE                  |               |      1 |      1 |      1 |00:00:00.01 |    5 |
|   2 |   BITMAP CONVERSION COUNT        |               |      1 |      3 |      1 |00:00:00.01 |    5 |
|   3 |    BITMAP OR                     |               |      1 |        |      1 |00:00:00.01 |    5 |
|   4 |     BITMAP CONVERSION FROM ROWIDS|               |      1 |        |      1 |00:00:00.01 |    3 |
|*  5 |      INDEX RANGE SCAN            | I_OBJECT_NAME |      1 |        |      1 |00:00:00.01 |    3 |
|   6 |     BITMAP CONVERSION FROM ROWIDS|               |      1 |        |      1 |00:00:00.01 |    2 |
|*  7 |      INDEX RANGE SCAN            | I_OBJECT_ID   |      1 |        |      1 |00:00:00.01 |    2 |
------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   5 - access("A"."OBJECT_NAME"='ICOL$')
   7 - access("A"."OBJECT_ID"=20)


SQL> select /*+gather_plan_statistics use_concat*/ count(1) from test a
  2      where a.object_id=20 or a.object_name='ICOL$';
  COUNT(1)
----------
         1
SQL> SELECT * FROM table(dbms_xplan.display_cursor(null,null,'iostats last'));
---------------------------------------------------------------------------------------------------------
| Id  | Operation                     | Name          | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
---------------------------------------------------------------------------------------------------------
|   1 |  SORT AGGREGATE               |               |      1 |      1 |      1 |00:00:00.01 |       7 |
|   2 |   CONCATENATION               |               |      1 |        |      1 |00:00:00.01 |       7 |
|   3 |    TABLE ACCESS BY INDEX ROWID| TEST          |      1 |      1 |      1 |00:00:00.01 |       3 |
|*  4 |     INDEX RANGE SCAN          | I_OBJECT_ID   |      1 |      1 |      1 |00:00:00.01 |       2 |
|*  5 |    TABLE ACCESS BY INDEX ROWID| TEST          |      1 |      2 |      0 |00:00:00.01 |       4 |
|*  6 |     INDEX RANGE SCAN          | I_OBJECT_NAME |      1 |      2 |      1 |00:00:00.01 |       3 |
---------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   4 - access("A"."OBJECT_ID"=20)
   5 - filter(LNNVL("A"."OBJECT_ID"=20))
   6 - access("A"."OBJECT_NAME"='ICOL$')

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值