table access by index rowid

table access by index rowid 

回表:在数据中,当查询数据的时候,在索引中查找索引后,获得该行的rowid,根据rowid再查询表中数据,就是回表。


--创建一个表, 索引只建立在object_id上

SQL> create table ml_1 as
  2  select * from dba_objects
  3  ;
 
Table created
 
SQL> create index idx_ml_1 on ml_1 (object_id);
 
Index created

--当select语句只有object_id时, 就不存在回表,因为索引包含此列。

unicomidmp@UNICOM>select object_id from ml_1 where  object_id =46;


Execution Plan
----------------------------------------------------------
Plan hash value: 328998971

-----------------------------------------------------------------------------
| Id  | Operation	 | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------
|   0 | SELECT STATEMENT |	    |	  1 |	 13 |	  1   (0)| 00:00:01 |
|*  1 |  INDEX RANGE SCAN| IDX_ML_1 |	  1 |	 13 |	  1   (0)| 00:00:01 |
-----------------------------------------------------------------------------

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

   1 - access("OBJECT_ID"=46)

Note
-----
   - dynamic sampling used for this statement (level=2)


Statistics
----------------------------------------------------------
	  7  recursive calls
	  0  db block gets
	 69  consistent gets
	  0  physical reads
	  0  redo size
	527  bytes sent via SQL*Net to client
	524  bytes received via SQL*Net from client
	  2  SQL*Net roundtrips to/from client
	  0  sorts (memory)
	  0  sorts (disk)
	  1  rows processed


--当select不仅仅有object_id列,还有其他列, 这时就需要回表。

unicomidmp@UNICOM>select status,object_id from ml_1 where  object_id =46;


Execution Plan
----------------------------------------------------------
Plan hash value: 1099796311

----------------------------------------------------------------------------------------
| Id  | Operation		    | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT	    |	       |     1 |    18 |     2	 (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| ML_1     |     1 |    18 |     2	 (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN	    | IDX_ML_1 |     1 |       |     1	 (0)| 00:00:01 |
----------------------------------------------------------------------------------------

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

   2 - access("OBJECT_ID"=46)

Note
-----
   - dynamic sampling used for this statement (level=2)


Statistics
----------------------------------------------------------
	 11  recursive calls
	  0  db block gets
	 72  consistent gets
	  0  physical reads
	  0  redo size
	601  bytes sent via SQL*Net to client
	524  bytes received via SQL*Net from client
	  2  SQL*Net roundtrips to/from client
	  0  sorts (memory)
	  0  sorts (disk)
	  1  rows processed


--所以并不是每次查询,都要走索引才是最优。


结论: 

如果在obiect_id上建立索引,那么在执行该条SQL语句时,先进行索引扫描,在索引中找到 obiect_id=46 所在的位置(一般只需要扫描3个块数据即可)
,获得该行的ROWID,根据其ROWID再查询数据(回表),如果所查找的数据量较少,则回表次数就少。如上面的例子,
要查询的数据只有 obiect_id在索引中,status并不在索引中,那么就要回表一次查询status,如果status也在索引中,那么就不需要回表。
如果索引查询的数据量大, 那么回表的次数就多, 索引扫描的io块+回表的io >  全表扫描io  ,此时就不能用索引。  即 no_index(x);



--end---


mengl   2016-5-22 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值