oracle TABLE ACCESS BY INDEX 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 結論

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


 

 

 



 


發佈了51 篇原創文章 · 獲贊 99 · 訪問量 54萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章