oracle開發系列(三)TABLE ACCESS BY INDEX ROWID 你不知道的索引回表,rowid回表

來源:互聯網
上載者:User

oracle開發系列(三)TABLE ACCESS BY INDEX ROWID 你不知道的索引回表,rowid回表
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)




看了下執行計畫 是這樣的:




 從上面的執行計畫來看 也是走了索引的 是索引範圍掃描。


2 解決

搞不明白 ,決定用count(*) 試試。

執行時間情況如下:


時間很快,1s不到。差別很大,感覺很奇怪 就比較了一下 兩者的執行計畫,下面是count(*)的執行計畫


 

 

對比了下 發現 慢的那個 多了個 TABLE ACCESS BY INDEX ROWID。


3 結論

得出原因:索引有一個單獨的Block Storage,根據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);

 

 

 

select COUNT(1) AS countnum

  fromiodso.qos_cnst_busilog_td x

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


 

 

 



 


相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.