table access by index rowid

来源:互联网 发布:cad制图机械软件 编辑:程序博客网 时间:2024/05/18 16:54

原文地址:http://blog.csdn.net/shushugood/article/details/51475825


table access by index rowid 

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


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

[html] view plain copy
  1. SQL> create table ml_1 as  
  2.   2  select * from dba_objects  
  3.   3  ;  
  4.    
  5. Table created  
  6.    
  7. SQL> create index idx_ml_1 on ml_1 (object_id);  
  8.    
  9. Index created  

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

[html] view plain copy
  1. unicomidmp@UNICOM>select object_id from ml_1 where  object_id =46;  
  2.   
  3.   
  4. Execution Plan  
  5. ----------------------------------------------------------  
  6. Plan hash value: 328998971  
  7.   
  8. -----------------------------------------------------------------------------  
  9. | Id  | Operation    | Name     | Rows  | Bytes | Cost (%CPU)| Time     |  
  10. -----------------------------------------------------------------------------  
  11. |   0 | SELECT STATEMENT |      |     1 |    13 |     1   (0)| 00:00:01 |  
  12. |*  1 |  INDEX RANGE SCAN| IDX_ML_1 |     1 |    13 |     1   (0)| 00:00:01 |  
  13. -----------------------------------------------------------------------------  
  14.   
  15. Predicate Information (identified by operation id):  
  16. ---------------------------------------------------  
  17.   
  18.    1 - access("OBJECT_ID"=46)  
  19.   
  20. Note  
  21. -----  
  22.    - dynamic sampling used for this statement (level=2)  
  23.   
  24.   
  25. Statistics  
  26. ----------------------------------------------------------  
  27.       7  recursive calls  
  28.       0  db block gets  
  29.      69  consistent gets  
  30.       0  physical reads  
  31.       0  redo size  
  32.     527  bytes sent via SQL*Net to client  
  33.     524  bytes received via SQL*Net from client  
  34.       2  SQL*Net roundtrips to/from client  
  35.       0  sorts (memory)  
  36.       0  sorts (disk)  
  37.       1  rows processed  


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

[html] view plain copy
  1. unicomidmp@UNICOM>select status,object_id from ml_1 where  object_id =46;  
  2.   
  3.   
  4. Execution Plan  
  5. ----------------------------------------------------------  
  6. Plan hash value: 1099796311  
  7.   
  8. ----------------------------------------------------------------------------------------  
  9. | Id  | Operation           | Name     | Rows  | Bytes | Cost (%CPU)| Time     |  
  10. ----------------------------------------------------------------------------------------  
  11. |   0 | SELECT STATEMENT        |          |     1 |    18 |     2   (0)| 00:00:01 |  
  12. |   1 |  TABLE ACCESS BY INDEX ROWID| ML_1     |     1 |    18 |     2   (0)| 00:00:01 |  
  13. |*  2 |   INDEX RANGE SCAN      | IDX_ML_1 |     1 |       |     1   (0)| 00:00:01 |  
  14. ----------------------------------------------------------------------------------------  
  15.   
  16. Predicate Information (identified by operation id):  
  17. ---------------------------------------------------  
  18.   
  19.    2 - access("OBJECT_ID"=46)  
  20.   
  21. Note  
  22. -----  
  23.    - dynamic sampling used for this statement (level=2)  
  24.   
  25.   
  26. Statistics  
  27. ----------------------------------------------------------  
  28.      11  recursive calls  
  29.       0  db block gets  
  30.      72  consistent gets  
  31.       0  physical reads  
  32.       0  redo size  
  33.     601  bytes sent via SQL*Net to client  
  34.     524  bytes received via SQL*Net from client  
  35.       2  SQL*Net roundtrips to/from client  
  36.       0  sorts (memory)  
  37.       0  sorts (disk)  
  38.       1  rows processed  


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


结论: 

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



--end---