oracle执行计划结果分析_两个执行计划看Oracle回表(49秒VS1秒)

概述

今天主要讲一下table access by index rowid概念,关于回表方面的内容,先看两个执行计划:

b965d605d24dab41a912f22237658797.png
027b4014df62e3a58a463360e39df2dc.png

上面两个执行计划看起来好像没啥区别,都走了索引,为什么一个要49秒,一个却1秒呢?


仔细对比就可以发现慢的那个多了个TABLE ACCESS BY INDEX ROWID

1秒的执行计划是因为索引有一个单独的块存储,根据oper_time 统计表的数据量时 只需要在索引的块里面统计数据量就可以了,所以比较快。而用了count(serialid) 的执行计划是因为 索引中保存的是字段的值和该值对应的rowid,根据索引进行查找,索引范围扫描后,就会返回该block的rowid,然后根据rowid直接去block上去我们需要的数据,因此就出现了:TABLE ACCESS BY INDEX ROWID。因为还要根据rowid回表的数据块上查询数据,所以速度慢了很多。这个也叫做回表。


实验--测试回表

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

create table ml_1 as select * from dba_objects;create index idx_ml_1 on ml_1 (object_id);
9ba7eeb0c3a8041cfe1e4769f7ab7fe8.png

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

select object_id from ml_1 where object_id =46;
823175ac1756c6b201de56645e0e9623.png

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

select status,object_id from ml_1 where object_id =46;
b5ca50ad5c41a82b07db7530c0055bdf.png

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


结论:

如果在obiect_id上建立索引,那么在执行该条SQL语句时,先进行索引扫描,在索引中找到 obiect_id=46 所在的位置(一般只需要扫描3个块数据即可),获得该行的ROWID,根据其ROWID再查询数据(回表),如果所查找的数据量较少,则回表次数就少。如上面的例子,

要查询的数据只有 obiect_id,在索引中,status并不在索引中,那么就要回表一次查询status,如果status也在索引中,那么就不需要回表。

如果索引查询的数据量大, 那么回表的次数就多, 索引扫描的io块+回表的io > 全表扫描io ,此时就不能用索引。 即 no_index(x);

后面小编会分享更多devops和DBA方面的内容,感兴趣的朋友可以关注一下~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值