2010-01-21 22 views
29

我主要是一個Actionscript開發人員,決不是SQL專家,但有時我不得不開發簡單的服務器端的東西。所以,我想我會問更多有經驗的人關於標題中的問題。使用基數較低的索引是否有意義?

我的理解是,通過在一個只包含幾個不同值的列中設置索引,你並不會獲得太多收益。我有一個列保存一個布爾值(實際上它是一個小的int,但我用它作爲標誌),並且這個列用於大多數查詢的WHERE子句中。在理論上的「平均」情況下,一半的記錄值將爲1,另一半爲0.因此,在這種情況下,數據庫引擎可以避免全表掃描,但是無論如何都必須讀取很多行(總排/ 2)。

那麼,我應該讓這個列成爲索引嗎?

爲了記錄,我使用的是Mysql 5,但是我更關心爲什麼它沒有意義地索引一個列,我知道這將有一個低基數的一般理由。

在此先感謝。

回答

2

我通常會做一個簡單的「有索引」vs「不要」索引測試。根據我的經驗,您可以在使用ORDER BY索引列的查詢中獲得大部分性能。如果您對該列進行了任何排序,索引最有可能有所幫助。

+0

感謝您的回答。在這種情況下,我並未在該列上排序。它只是將記錄標記爲啓用/禁用。基本上,我將它用於軟刪除。這就是爲什麼我必須在大多數查詢的WHERE子句中使用它。 – 2010-01-21 21:58:10

2

恕我直言,它的用處有限。我認爲在大多數情況下,除了可能幫助更多的標誌之外,您在查詢中還使用了其他標準。

在50%的時候,我可能會做一些基準測試,看看它是否有很大的不同。

8

在組合索引中包含布爾值字段可能是值得的。例如,如果你有這通常需要按照日期來排序消息的大表,但你也有一個布爾刪除領域,所以你經常查詢這樣的:

SELECT ... FROM Messages WHERE Deleted = 0 AND Date BETWEEN @start AND @end 

你一定會能從中受益刪除日期字段上的複合索引。

+0

謝謝。也許我應該對複合指數做一些研究(我只知道存在,但並沒有真正使用它們)。我以非常類似於示例代碼的方式使用此列(儘管存在連接和其他內容,但WHERE子句始終具有用於標記軟刪除的此標誌)。 – 2010-01-21 22:03:53

56

索引可以幫助甚至在低基數的域,如果:

  1. 相較於其他值可能值之一是非常罕見的,你搜索。

    舉例來說,很少有色盲的女性,所以這個查詢:

    SELECT * 
    FROM color_blind_people 
    WHERE gender = 'F' 
    

    將最有可能從指數上gender受益。

  2. 當值傾向於在表的順序進行分組:

    SELECT * 
    FROM records_from_2008 
    WHERE year = 2010 
    LIMIT 1 
    

    雖然這裏只有3不同的幾年,是最有可能加入前幾年記錄第一所以很多記錄必須是如果不是索引,則在返回第一個2010記錄之前進行掃描。

  3. 當你需要ORDER BY/LIMIT

    SELECT * 
    FROM people 
    ORDER BY 
         gender, id 
    LIMIT 1 
    

    沒有索引,filesort將需要。儘管對LIMIT做了一些優化,但它仍然需要全表掃描。

  4. 當指數涵蓋了在查詢中使用的所有字段:

    CREATE INDEX (low_cardinality_record, value) 
    
    SELECT SUM(value) 
    FROM mytable 
    WHERE low_cardinality_record = 3 
    
  5. 當你需要DISTINCT

    SELECT DISTINCT color 
    FROM tshirts 
    

    MySQL將使用INDEX FOR GROUP-BY,如果你有幾種顏色,此查詢即使擁有數百萬條記錄也會立即實現。

    這是低基數字段上的索引是更多高於基數高字段時的情況。

注意,如果DML性能沒有太大的問題,那麼就可以安全地創建索引。

如果優化器認爲索引效率低下,索引就不會被使用。

相關問題