[20130910]12C执行计划的TABLE ACCESS BY INDEX ROWID BATCHED(补充).txt

[20130910]12C执行计划的TABLE ACCESS BY INDEX ROWID BATCHED(补充).txt

链接
http://space.itpub.net/267265/viewspace-772371

写了12c下在范围扫描时可能出现的TABLE ACCESS BY INDEX ROWID BATCHED,这是一种新的执行方式,能够
提高执行效率,特别在数据聚集很好的情况下。

既然是12c的一个特性应该有一个参数关闭这个特性。重复前面的例子:

1.建立测试环境:

SCOTT@test01p> @ver
BANNER                                                                               CON_ID
-------------------------------------------------------------------------------- ----------
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production              0

SCOTT@test01p> create table t (id number,name varchar2(20));
Table created.

--打开3个session,分别执行如下:
-session 1:
insert into t values (1,lpad('a',20,'a'));
commit ;

-session 2:
insert into t  values (2,lpad('b',20,'b'));
commit ;

-session 3:
insert into t  values (3,lpad('c',20,'c'));
commit ;

insert into t  select rownum+3 id ,lpad('x',20,'x') name from dual connect by level commit ;

--这样操作可以导致id=1在一个数据块id=2,3在另外的数据块。

SCOTT@test01p> select rowid ,t.* from t where id between 1 and 3;
ROWID                      ID NAME
------------------ ---------- --------------------
AAAWxnAAJAAAAC1AAA          1 aaaaaaaaaaaaaaaaaaaa
AAAWxnAAJAAAAC3AAA          2 bbbbbbbbbbbbbbbbbbbb
AAAWxnAAJAAAAC3AAB          3 cccccccccccccccccccc

COTT@test01p> @lookup_rowid AAAWxnAAJAAAAC1AAA
   OBJECT       FILE      BLOCK        ROW DBA
--------- ---------- ---------- ---------- --------------------
    93287          9        181          0 9,181
COTT@test01p> @lookup_rowid AAAWxnAAJAAAAC3AAA
   OBJECT       FILE      BLOCK        ROW DBA
--------- ---------- ---------- ---------- --------------------
    93287          9        183          0 9,183

SCOTT@test01p> create unique index i_t_id on t(id);
Index created.

--分析表
SCOTT@test01p> execute dbms_stats.gather_table_stats(user,'t');
PL/SQL procedure successfully completed.

2.测试

SCOTT@test01p> @dpc '' ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  3uy89r3c5z5yy, child number 0
-------------------------------------
select * from t where id between 1 and 100
Plan hash value: 3446268138
----------------------------------------------------------------------------
| Id  | Operation                           | Name   | E-Rows | Cost (%CPU)|
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |        |        |     3 (100)|
|   1 |  TABLE ACCESS BY INDEX ROWID BATCHED| T      |    100 |     3   (0)|
|*  2 |   INDEX RANGE SCAN                  | I_T_ID |    100 |     1   (0)|
----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("ID">=1 AND "ID"--即使扫描全部数据,选择的也是使用索引。
SYS@test01p> @hide _optimizer_batch_table_access_by_rowid
old  10:  and lower(a.ksppinm) like lower('%&1%')
new  10:  and lower(a.ksppinm) like lower('%_optimizer_batch_table_access_by_rowid%')
NAME                                     DESCRIPTION                                DEFAULT_VALUE  SESSION_VALUE  SYSTEM_VALUE
---------------------------------------- ------------------------------------------ -------------- -------------- ------------
_optimizer_batch_table_access_by_rowid   enable table access by ROWID IO batching   TRUE           TRUE           TRUE
SCOTT@test01p> alter session set "_optimizer_batch_table_access_by_rowid"=false;
Session altered.
SCOTT@test01p> @dpc '' ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  3uy89r3c5z5yy, child number 1
-------------------------------------
select * from t where id between 1 and 100
Plan hash value: 4153437776
--------------------------------------------------------------------
| Id  | Operation                   | Name   | E-Rows | Cost (%CPU)|
--------------------------------------------------------------------
|   0 | SELECT STATEMENT            |        |        |     3 (100)|
|   1 |  TABLE ACCESS BY INDEX ROWID| T      |    100 |     3   (0)|
|*  2 |   INDEX RANGE SCAN          | I_T_ID |    100 |     1   (0)|
--------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("ID">=1 AND "ID"--回到原来的模式,奇怪的是为什么选择的还是INDEX RANGE SCAN+ TABLE ACCESS BY INDEX ROWID扫描呢?--正常应该选择全表扫描。
SCOTT@test01p> set autot traceonly
SCOTT@test01p> select * from t where id between 1 and 100;
100 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 4153437776
--------------------------------------------------------------------------------------
| Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |        |   100 |  2400 |     3   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T      |   100 |  2400 |     3   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | I_T_ID |   100 |       |     1   (0)| 00:00:01 |
--------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("ID">=1 AND "ID"
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          4  consistent gets
          0  physical reads
          0  redo size
       3548  bytes sent via SQL*Net to client
        544  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
        100  rows processed

--奇怪逻辑读还是4.难道oracle改进了什么?能力如此,oracle许多东西不了解,那位知道给出答案!

时间: 2024-10-06 07:23:06

[20130910]12C执行计划的TABLE ACCESS BY INDEX ROWID BATCHED(补充).txt的相关文章

[20130909]12C执行计划的TABLE ACCESS BY INDEX ROWID BATCHED.txt

[20130909]12C执行计划的TABLE ACCESS BY INDEX ROWID BATCHED.txt 在写[20130809]12c Clustering Factor.txt,链接 提到执行计划里面存在TABLE ACCESS BY INDEX ROWID BATCHED,这里的BATCHED表示什么? 自己不是很清楚. 既然多了一个batched,一定与原来的不同,具体含义是什么呢?做一些简单的探究: 1.建立测试环境: SCOTT@test01p> @ver BANNER  

Oracle 12C 执行计划提示TABLE ACCESS BY INDEX ROWID BATCHED

从Oracle 12C开始执行计划中可能会出现TABLE ACCESS BY INDEX ROWID BATCHED,官方的解释:TABLE ACCESS BY INDEX ROWID BATCHED:means that the database retrieves a few rowids from the index, and then attempts to access rows in block order to improve the clustering and reduce t

oracle 12c R1执行计划新特性-table access by index rowid batched和INMOMEORY OPTION

oracle 12c R1执行计划在索引回表阶段oracle推出了batched特性,类似于oracle 11g中在nested loop中被驱动表回表时的向量IO,也是为了有效的解决表中数据无序性(索引的聚簇因子),下面看实际测试用例: 数据库版本:12.1.0.2版本 sys@CRMDB2> explain plan for SELECT offering_inst_id,        offering_id,        owner_party_role_type,        ow

Oracle 全表扫描及其执行计划(full table scan)

    全表扫描是Oracle访问数据库表是较为常见的访问方式之一.很多朋友一看到SQL语句执行计划中的全表扫描,就要考虑对其进行修理一番.全表扫描的存在,的确存在可能优化的余地.但事实上很多时候全表扫描也并非是最低效的,完全要看不同的情形与场合,任一方式都是有利有弊的,也就是具体情况要具体分析.本文描述了什么是全表扫描以及何时发生全表扫描,何时全表扫描才低效.  本文涉及到的相关链接:     高水位线和全表扫描      启用 AUTOTRACE 功能     Oracle 测试常用表BIG

MySQL执行计划extra中的using index 和 using where using index 的区别

原文:MySQL执行计划extra中的using index 和 using where using index 的区别   本文出处:http://www.cnblogs.com/wy123/p/7366486.html (保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错误进行修正或补充,无他)   mysql执行计划中的extra列中表明了执行计划的每一步中的实现细节,其中包含了与索引相关的一些细节信息其中跟索引有关的using index

oracle_执行计划_谓词信息和数据获取(access and filter区别) (转)

These two terms in the Predicate Information section indicate when the data source is reduced. Simply, access means only retrieve those records meeting the condition and ignore others. Filter means *after* you already got the data, go through them al

【性能优化】执行计划与直方图

在Oracle中直方图是一种对数据分布质量情况进行描述的工具.它会按照某一列不同值出现数量多少,以及出现的频率高低来绘制数据的分布情况,以便能够指导优化器根据数据的分布做出正确的选择.在某些情况下,表的列中的数值分布将会影响优化器使用索引还是执行全表扫描的决策.当 where 子句的值具有不成比例数量的数值时,将出现这种情况,使得全表扫描比索引访问的成本更低.这种情况下如果where 子句的过滤谓词列之上上有一个合理的正确的直方图,将会对优化器做出正确的选择发挥巨大的作用,使得SQL语句执行成本

Oracle如何查询访问同一表的两个以上索引(三)INDEX HASH JOIN执行计划

经常看到有人提出这样的疑问,我在同一张表上建立了多个索引,为什么Oracle每次都选择一个,而不能同时利用多个索引呢.一般来说,常见的访问同一张表的两个以上索引,存在三种情况,AND-EQUAL.INDEX HASH JOIN和BITMAP INDEX AND/OR. 此外,还有一个设计上的疑问,如果有A.B.C三个字段,都可能作为查询条件,是建立多个复合索引好,还是建立三个单列的索引.这个问题之所以不好回答是因为和业务或者说和查询的模式有很大的关系,不过如果理解了Oracle什么时候会选择一个

【Oracle】如何查看sql 执行计划的历史变更

   今天中午,突然接收到active session 数目飙高的报警,查看数据库,对于一个OLTP 类型的查询本应该走index range scan 却变成全部是 direct path read ,所有的sql 走了全表扫描.悲剧的是那个表是一个历史表 185G..故造成了许多session堆积,前台应用受到影响.回到问题本身,如果查看sql执行计划的变更?? oracle 10G 以后可以通过下面的三个视图查询到sql执行计划的历史信息: DBA_HIST_SQL_PLAN DBA_HI