在第二次執行時,優化器會依據實際的基數重新決策生成執行計劃,但是需要注意的是,當使用更準確的基數重新生成執行計劃時,生成的執行計劃與第一次時使用的執行計劃完全有可能是相同的。這個技術的出現是由于優化器在一些情況下不能很好的去計算基數的數值,比如:統計信息缺失或陳舊、多謂詞、直方圖缺失等等。
報重慶思莊19c OCP周末班,送學習大禮包
Oracle只針對下面情況開啟CFB:
① 沒有收集表的統計信息,并且動態采樣(Dynamic Sampling)也沒有開啟。
② 查詢條件復雜(比如條件有函數)或者涉及多列,但卻沒有收集擴展的統計信息(Extended Statistics)。
在這幾種情況下,CBO是無法估算出準確的Cardinality的。針對上述情況,Oracle會監控操作的實際行數(A-Row),然后對比CBO估算的行數(E-Row)。如果兩個值相差很大,那么就記錄實際行數(A-Row),做上標記。下次執行時再次進行硬解析,根據實際行數來重新生成執行計劃。如果兩個值相差不大,那么CBO就不再監控這條SQL語句。
Oracle 11gR2針對此特性,也專門在V$SQL_SHARED_CURSOR中增加了USE_FEEDBACK_STATS列來記錄SQL是否使用了基數反饋。基數反饋的開啟和關閉通過一個隱含參數“_OPTIMIZER_USE_FEEDBACK”來控制,該參數默認為TRUE,表示開啟技術反饋特性。此參數除了可以在SESSION和SYSTEM級別進行設置之外,還可以在SQL語句級使用Hint進行開啟和關閉,如下所示:
SELECT /*+ OPT_PARAM('_OPTIMIZER_USE_FEEDBACK' 'FALSE') */ COUNT(*) FROM TEST;
SELECT /*+ OPT_PARAM('_OPTIMIZER_USE_FEEDBACK' 'TRUE') */ COUNT(*) FROM TEST;
需要注意的是,如果動態采樣被啟用,那么是不會使用基數反饋特性的。若使用了該特性則在執行計劃的Note部分可以看到“cardinality feedback used for this statement”字樣。基數反饋在Oracle 12c上得到更進一步的擴展稱為統計反饋(Statistics Feedback),并且成為Oracle 12c自動重新優化(Automatic Reoptimization)的一部分。但是由于CFB的評估結果數據只存在內存中(重啟之后就會丟失),在會話之間是不可共用的,并且由于在Oracle 11g中存在過多的Bug,常見的問題就是在第二次執行SQL時候性能下降很多。因此在Oracle 11g的數據庫中往往會對11.2.0.4以下的數據庫會將該特性關閉。