Oracle
為什麼Oracle在這裡使用索引?
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 是否做出了錯誤的假設以及如何為其提供更好的資訊——而不是假設它被破壞和/或試圖規避它。