码迷,mamicode.com
首页 > 数据库 > 详细

oracle开发系列(三)TABLE ACCESS BY INDEX ROWID 你不知道的索引回表

时间:2014-11-11 16:44:10      阅读:248      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   io   color   ar   os   sp   数据   

1 引言


最近系统经常提示一个sql查询时间过长的问题,看了一下就是一个每天按照时间戳统计前一天量的sql。
表总的数据量为53483065。

语句如下:

select count(x.serial_id) as countnum
  from iodso.qos_cnst_busilog_td x
 where x.oper_time between trunc(sysdate- 1) and trunc(sysdate);



执行时间情况如下:(执行要49s)

bubuko.com,布布扣


看了下执行计划 是这样的:


bubuko.com,布布扣


 从上面的执行计划来看 也是走了索引的 是索引范围扫描。


2 解决

搞不明白 ,决定用count(*) 试试。

执行时间情况如下:

bubuko.com,布布扣


时间很快,1s不到。差别很大,感觉很奇怪 就比较了一下 两者的执行计划,下面是count(*)的执行计划


 bubuko.com,布布扣

 

对比了下 发现 慢的那个 多了个 TABLE ACCESS BY INDEX ROWID。


3 结论

得出原因:索引有一个单独的块存储,根据oper_time 统计表的数据量时 只需要在索引的块里面统计数据量就可以了,所以比较快。

那个count(serialid) :

Oracle 索引中保存的是我们字段的值和该值对应的rowid,我们根据索引进行查找,索引范围扫描后,就会返回该block的rowid,然后根据rowid直接去block上去我们需要的数据,因此就出现了:TABLE ACCESS BY INDEX ROWID

因为还要根据rowid回表的数据块上查询数据,所以速度慢了很多。



4 备注:

下面两个查询的执行时间也很快,因为执行计划与count(*)都是一样的。


select COUNT(x.oper_time) AS countnum

  fromiodso.qos_cnst_busilog_td x

 where x.oper_timebetween trunc(sysdate - 1) and trunc(sysdate);

 bubuko.com,布布扣

 bubuko.com,布布扣

 

select COUNT(1) AS countnum

  fromiodso.qos_cnst_busilog_td x

 where x.oper_timebetween trunc(sysdate - 1) and trunc(sysdate);


 bubuko.com,布布扣bubuko.com,布布扣

 

 



 


oracle开发系列(三)TABLE ACCESS BY INDEX ROWID 你不知道的索引回表

标签:style   blog   http   io   color   ar   os   sp   数据   

原文地址:http://blog.csdn.net/xiaohai798/article/details/39559021

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!