2009-12-10 15 views
7

我有一張表,最多可以有5000.000行。此表中的一列僅用於查詢,但該列只有5個可能值,目前我得到10.000行,根據解釋計劃,在該列上使用我的索引是沒有意義的。只有5個不同值的列上的索引 - 是否值得?

請問它曾經,或者我不應該與指數打擾

編輯:這是兩個在此刻解釋計劃 Without index http://img706.imageshack.us/img706/1903/noindex.pngWith forced index via hints http://img692.imageshack.us/img692/8205/indexp.png 後者像我強迫索引的使用提示。

+0

當然,這取決於您的查詢。這個例子給出了你按照一個標準過濾的情況:'FREQUENCYID'。如果您希望稍後有其他條件(可能使用動態查詢)並且也會過濾它們,那麼索引會更有意義。 –

回答

7

這取決於幾件事情。

首先,分配值。如果您只有五個不同的值,但其中一個值佔表中99.9999%的行數,那麼顯然您不希望優化器使用該值作爲索引值,但可能需要將其用於其他值。在這種情況下,值得使用基於函數的索引來確保您只索引感興趣的值,而不是僅佔用空間的值。

其次,有沒有查詢可以使用該索引應答而無需訪問表?

請注意,這不僅僅是將要訪問的行的百分比,還有需要訪問的表的塊數。例如,如果您有一個平均每塊1000個塊和30行的表,並且一列包含30個不同的值(每個塊存在1000行),那麼需要訪問以讀取每行的根據行如何分佈,單個值在1000/30 = 34(值得使用索引)和1000(不值得使用索引)之間變化。這是由索引的聚類因子表示的 - 如果它的值接近表中的行數,那麼索引不太可能被使用,並且如果它接近塊的數量,那麼它更可能是用過的。

此外,您可能會看索引壓縮,看看是否節省您的空間。

請注意位圖索引 - 它們對於同時受多個會話修改的系統不友好(例如,兩個人同時向索引表中插入行)。

一個更有效的策略,如果你想提高這些查詢的效率,這些查詢的謂詞就是使用分區,部分是因爲查詢中的分區修剪,也是因爲優化器可用的統計數據改進時它知道只有一個分區將被訪問,並且可以使用分區級統計信息而不是全局統計信息。

1

如果布萊恩規模會繼續擴大你提到

達5.000.000行

我會建議創建一個索引。

1

可能是最簡單的方法,它不去猜測,但實際上嘗試。

但在我看來,你正在比較執行計劃,以找到最佳方法。這不可靠。優化程序可能沒有適當的信息來選擇最佳計劃(例如,如果您的值分佈不均勻且沒有直方圖)。在解釋計劃中看「成本」也沒有意義。

更好的方法是比較邏輯IO。運行SQL * Plus,例如set autotrace traceonly,然後運行您的查詢(使用和不使用索引)並比較「一致性獲取」數字。越少越好。

關於LIO的重要性:article by Cary Millsap

0

使用典型查詢進行測試,查看哪種方式更快。

您可能會發現,全表掃描的平均速度比Rowid的索引範圍掃描+表訪問速度要快 - 在這種情況下,Oracle確實是正確的。

另一方面,也許有數據模式,對於大多數查詢,最好使用索引 - 在這種情況下,您可能需要添加INDEX提示。

2

該指數將在以下情況下是有用的:

  • 當您搜索罕見FREQUENCYID的。同樣,只有您的10,000,000行的10行有FREQUENCYID = 1並且您在搜索它。

  • 當您在查詢中未使用除FREQUENCYID之外的其他列時。這個查詢:

    SELECT FREQUENCYID, COUNT(*) 
    FROM mytable 
    GROUP BY 
         FREQUENCYID 
    

    將受益於指數(實際上,INDEX FAST FULL SCANHASH AGGREGATE一起將最有可能被使用)

  • 當你的錶行很大,你在查詢中使用的所有列的索引。通過這種方式,所有索引都將被加入,而不是製作一個FULL TABLE SCAN。說,這個查詢:

    SELECT FREQUENCYID, OTHERCOLUMN 
    FROM mytable 
    WHERE FREQUENCYID = 2 
    

    可以通過ROWIDFREQUENCYIDOTHERCOLUMN從索引加盟值來進行。

相關問題