Oracle

為什麼Oracle在這裡使用索引?

  • September 30, 2011
Name     Null     Type      
-------- -------- --------- 
ID       NOT NULL NUMBER(4) 
GROUP_ID          NUMBER(4) 
TEXT              CLOB      

上有一個 btree 索引group_id。這是每個有多少行group_id和相應的百分比:

GROUP_ID               COUNT                  PCT                    
---------------------- ---------------------- ---------------------- 
1                      1                      1                      
2                      2                      1                      
3                      4                      3                      
4                      8                      6                      
5                      16                     12                     
6                      32                     24                     
7                      64                     47                     
8                      9                      7                      

我跑了這個

EXEC DBMS_STATS.GATHER_SCHEMA_STATS(ownname=>'TEST', cascade=>true);

如果我理解正確,它將為優化器收集統計資訊。

現在,我記得看到 Oracle 不會使用索引,而是在檢索超過 5% 左右的所有行時執行全表掃描。但是,當我執行此查詢時,它僅在 7 時才開始執行 FTS group_id,佔所有行的 47%。

這是它應該的方式嗎?

我記得看到如果 Oracle 檢索的行超過 5% 左右,Oracle 不會使用索引並執行全表掃描。

這是“經驗法則”,不應被視為預測。Oracle CBO根據估計的選項“成本”選擇執行計劃。估計成本將取決於各種參數,並且複雜性隨著每個 Oracle 版本的增加而增加。

您可以使用提示explain plan更詳細地了解兩個計劃的相對成本 - 但這應該在單個查詢中完成,因為不能保證“成本”是單個計劃之外的絕對度量:

select /*+ FULL(foo) */ * from foo where group_id=10
union all
select /*+ INDEX(i_foo) */ * from foo where group_id=10;

範例解釋具有相對成本的計劃

這是它應該的方式嗎?

簡而言之:是的。

除非您確定了特定的性能問題,否則您應該相信 CBO 會選擇正確的路徑(例如,除了上面的測試和試驗之外,不要使用提示)。如果您發現了問題,下一步是開始調查 CBO 是否做出了錯誤的假設以及如何為其提供更好的資訊——而不是假設它被破壞和/或試圖規避它。

引用自:https://dba.stackexchange.com/questions/5632