名詞
Cardinality:
優化器在計算成本的時候,需要從統計信息中取得數據,然后去估計每一步操作所涉及的行數,叫做Cardinality。
比如,一張表T有1000行數據,列COL1上沒有直方圖,沒有空值,並且不重復的值(distinct value)有500個。那么,在使用條件“WHERE COL1=<VALUE>”去訪問表的時候,優化器會假設數據均勻分布,它估計出會有1000/500=2行被選出來,2就是這步操作的Cardinality。
優化器在計算成本的時候,需要從統計信息中取得數據,然后去估計每一步操作所涉及的行數,叫做Cardinality。
比如,一張表T有1000行數據,列COL1上沒有直方圖,沒有空值,並且不重復的值(distinct value)有500個。那么,在使用條件“WHERE COL1=<VALUE>”去訪問表的時候,優化器會假設數據均勻分布,它估計出會有1000/500=2行被選出來,2就是這步操作的Cardinality。
通常情況下,Cardinality越准確,生成的執行計划就會越高效。
適用情況
Oracle只針對下面情況開啟CFB:
o 沒有收集表的統計信息,並且dynamic sampling 也沒有開啟。
或者
o 查詢條件復雜(比如條件有函數)或者涉及多列,但卻沒有收集擴展的統計信息(extended statistics)
或者
o 查詢條件復雜(比如條件有函數)或者涉及多列,但卻沒有收集擴展的統計信息(extended statistics)
在這幾種情況下,CBO是無法估算出准確的Cardinality的。
過程描述
1. 針對上述情況,Oracle會監控操作的實際行數(A-Row),然后對比CBO估算的行數(E-Row)。
2. 如果兩個值相差很大,就記錄實際行數(A-Row),做上標記。下次執行時再次進行硬解析,根據實際行數來重新生成執行計划。
3. 如果兩個值相差不大,CBO就不再監控這條SQL語句。
2. 如果兩個值相差很大,就記錄實際行數(A-Row),做上標記。下次執行時再次進行硬解析,根據實際行數來重新生成執行計划。
3. 如果兩個值相差不大,CBO就不再監控這條SQL語句。
驗證
如果你在執行計划的最后看到下面這段文字,說明這個執行在生成時啟用了CFB。
Note
-----
- cardinality feedback used for this statement
-----
- cardinality feedback used for this statement
禁用
如果你被這個特性困擾,那么可以把它關閉。 具體操作請參考Note 1344937.1
參考
Cardinality Feedback - Frequently Asked Questions (Doc ID 1344937.1)