搜尋此網誌

星期日, 3月 18, 2012

[DBA] 一句sql可能因為指定的內容,造成Full Table Scan & Index Scan. 20120319

一句sql可 能因為指定的內容,可能造成Full Table Scan or Index Scan.
今天在看sql的資料中,發現了這個有趣現象,供大家討論。

原sql為:
SQL> SELECT MAX (joblog0_.date_created) AS col_0_0_
  FROM newsec.job_log joblog0_
 WHERE joblog0_.job_name = :1 AND joblog0_.log_type = 'Finish';

其執行計劃:

看來是有用到indexcost也 相當低

不過,我在系統的統計中發現一個問題




因此查詢一下此sql的歷史的執行計劃




結果同一個sql,有二種不同的執行結果,一個有採用到Index , 一個卻沒有用到index

因此我好奇的查了一下table的 資料,發現job_name log_type 建立的index 都 正常

由於job_name 為動態變數,而log_type 為 固定值(Finish),所以我以job_name的 值帶入後發現,若以job_name='JOB_76'帶入,就會造成Full Table Scan


但若以job_name='JOB_151'帶 入,則又是正常的index scan

我們以job_name 來做資料的分類
會發現,job_name = 'JOB_76' 的 資料量有高達26386筆,而job_150job_148也 是相當多筆。
故事還沒完
照道理來說,若JOB_76full table scan的話,那比它多的應該也都是full table scan
然而實際狀況並非如此。JOB_150有 高達8萬多筆,比job_762萬 多筆多出了三倍,居然是Index Scan。嚇死人了,見鬼了喲。

因此,我們再分析一下二個條件job_name & log_type='Finish'所 造成的筆數內容。
    JOB_76    JOB_148   JOB_150
     13179           0                      0

JOB_148 & JOB_150 都 是0筆,怎麼會一個是Full Table Scan, 一 個是Index Scan

我猜想這大概跟統計值有關係。果不其然,在JOB_LOG這 個table中,發現統計值過期了。


重 新analyzed 過後,則都能用到Index 了。


沒有留言: