一句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';
其執行計劃:
看來是有用到index,cost也 相當低
不過,我在系統的統計中發現一個問題
因此查詢一下此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_150與job_148也 是相當多筆。
故事還沒完
照道理來說,若JOB_76會full table scan的話,那比它多的應該也都是full table scan。
然而實際狀況並非如此。JOB_150有 高達8萬多筆,比job_76的2萬 多筆多出了三倍,居然是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 了。