什麼是字首索引
我們吃甘蔗的時候,若出現蟲蛀情況,我們不能判斷蟲蛀的範圍有大,如果為了省事,直接砍去若干節,蟲蛀殘留的概率就會小很多,但是很可能損失更多的可食用甘蔗。如果一點點地削,直至蟲蛀不再出現為止,看起來多花了點功夫,但是浪費的少,也只值得。
相比於砍甘蔗,MySQL 的全文索引類似於第一種方法,字首索引則像是第二種方法。
當需要以某個資料型別是字串的列為索引時,通常都是建立全文索引,通過全文匹配條件來篩選記錄。其實沒有必要,一種更好的辦法是:
可以索引開始的部分字元,這樣可以大大節約索引空間,從而提高索引效率
為什麼要使用字首索引
- 大大節約索引空間,從而提高索引效率
- 對於 BOLB、TEXT 或者很長的 VARCHAR 型別的列,必須使用字首索引。因為 MySQL 不允許索引這些列的完整長度
索引的選擇性
也許我們心中已經留下了字首索引效率高於全文索引的印象,但是字首的長度該保留多少呢?有沒有一個標準的值呢?換句話說,索引的長度與查詢效率之間呈現怎樣的關係?
首先,引入一個概念——索引的選擇性:
不重複的索引值(也稱基數)和資料表記錄總數(#T)的值,範圍從 1 / #T 到 1 之間。
索引的選擇性越高則查詢效率越高,因為選擇性高的索引可以讓 MySQL 在查詢時過濾掉更多的行。對比之下,唯一索引(值唯一,比如主鍵)的選擇性是 1,這是最好的索引選擇性,效能也是最好的。
字首索引會降低索引的選擇性,因為使用字首索引查詢出的基數很難完美匹配 #T,但是比起這些缺點,字首索引的好處簡直是大過天。
真正的難點在於:要選擇足夠長的字首以保證較高的選擇性,同時又不能太長。字首的長度應該使字首索引的選擇性接近索引整個列,即字首的“基數”應該接近於完整列的“基數”。
舉例說明
下面的例子,查詢軟體名稱,並統計其數量
第一列的統計數量則可認為是 #T,現在要查詢到最頻繁出現(基數接近 #T )的軟體名稱字首,直接從 7 個字首字母開始:
每個字首都比原來的軟體名稱出現的次更多,因此唯一字首比唯一軟體名稱要少得多。然後我們增加字首長度,直到這個字首的選擇性接近完整列的選擇性,此時的字首長度為 9:
試過 10,和 9 差不多,最後,選擇了字首長度為 9 的索引。
我的部落格地址:MySQL 高效能索引之字首索引