索引選擇性是什么
索引的選擇性,指的是不重復的索引值(基數)和表記錄數的比值。選擇性是索引篩選能力的一個指標。索引的取值范圍是 0—1 ,當選擇性越大,索引價值也就越大。
舉例說明:假如有一張表格,總共有一萬行的記錄,其中有一個性別列sex,這個列的包含選項就兩個:男/女。那么,這個時候,這一列創建索引的話,索引的選擇性為萬分之二,這時候,在性別這一列創建索引是沒有啥意義的。假設個極端情況,列內的數據都是女,那么索引的選擇性為萬分之一,其效率還不如直接進行全表掃描。如果是主鍵索引的話,那么選擇性為1,索引價值比較大。可以直接根據索引定位到數據。
索引選擇性計算
索引選擇性 = 基數 / 總行數
舉例:有個學校表 school ,學校名稱 school_nick 的索引選擇性為: SELECT COUNT(DISTINCT(school_nick))/COUNT(id) AS Selectivity FROM school;
結果如下:
school_nick 的選擇性為1,從選擇性方面分析,適合建立索引。
索引選擇性與前綴索引
前綴索引是用列的一部分字符去建立索引,更加節省空間(因為只使用一部分字符,索引建立時長度會降低),選擇合適的話,效率也會更高。具體見 mysql 索引及索引創建原則
這里主要介紹下,前綴索引在建立的時候,怎樣選擇一個合適的長度作為前綴索引的字符數。選擇性當然是越高越好,不過隨着字符數的增加,選擇性的提升會變得越來越不明顯。這里,就以學校表為例子,進行前綴索引的一個創建。
首先,我們通過剛才的測試已經知道,如果使用全部列作為索引的話,選擇性為1,是很好的。現在,我們取這一列的第一個字符,計算一個字符情況下的索引選擇性。代碼如下:
SELECT COUNT(DISTINCT(LEFT (school_nick, 1)))/COUNT(id) AS Selectivity FROM school;
結果如下:
可以看出,索引的選擇性很低了。然后,我們將前綴索引改為兩個字符、三個字符。。。依次得到結果如下:
在第九個字符的時候,選擇性為0.99 已經很接近1了。而且再添加字符的話,效果也不大,所以我們可以選擇九個字符作為 school_nick 的前綴索引。這樣索引長度僅為9 比字段長度255 短了特別多。
做一下性能對比:
school 表總共有17萬行的數據。分別在沒有索引,字段索引及前綴索引下按照學校名稱查詢一條記錄用時對比:
沒有索引:
全列索引:
前綴索引:
到這里,我們的額前綴索引就創建成功了,而且性能還是比較可觀的。