今天在讀一篇關於數據庫索引介紹的文章時,該文章提到了前綴索引,對於我這個搞數據庫應用開發那么多年的人來說,這個詞還真是一個新詞,沒用過。於是打算研究一番。
前綴索引似乎是MySQL中的一個概念,在SQL Server和Oracle中沒提出這個概念。於是就安裝了一個MySQL來做實驗,搞清楚前綴索引。
前綴索引說白了就是對文本的前幾個字符(具體是幾個字符在建立索引時指定)建立索引,這樣建立起來的索引更小,所以查詢更快。有點相當於Oracle中對字段使用Left函數,建立函數索引,只不過MySQL的這個前綴索引在查詢時是內部自動完成匹配的,並不需要使用left函數。
別的文章中提到:
MySQL 前綴索引能有效減小索引文件的大小,提高索引的速度。但是前綴索引也有它的壞處:MySQL 不能在 ORDER BY 或 GROUP BY 中使用前綴索引,也不能把它們用作覆蓋索引(Covering Index)。
建立前綴索引的語法為:
ALTER TABLE table_name ADD KEY(column_name(prefix_length));
這里最關鍵的參數就是prefix_length,這個值需要根據實際表的內容,得到合適的索引選擇性(Index Selectivity)。索引選擇性就是不重復的個數與總個數的比值。
from table_name
比如我們現在有個Employee表,其中有個FirstName字段,是varchar(50)的,我們查詢該字段的索引選擇性:
from Employee
得到結果0.7500,然后我們希望對FirstName建立前綴索引,希望前綴索引的選擇性能夠盡量貼近於對整個字段建立索引時的選擇性。我們先看看3個字符,如何:
from Employee
得到的結果是0.58784,好像差距有點大,我們再試一試4個字符呢:
from Employee
得到0.68919,已經提升了很多,再試一試5個字符,得到的結果是0.72297,這個結果與0.75已經很接近了,所以我們這里認為前綴長度5是一個合適的取值。所以我們可以為FirstName建立前綴索引:
建立前綴索引后查詢語句並不需要更改,如果我們要查詢所有FirstName為Devin的Employee,那么SQL仍然寫成:
from Employee e
where e.FirstName = ' Devin ';
下面總結一下什么情況下使用前綴索引:
- 字符串列(varchar,char,text等),需要進行全字段匹配或者前匹配。也就是=‘xxx’ 或者 like ‘xxx%'
- 字符串本身可能比較長,而且前幾個字符就開始不相同。比如我們對中國人的姓名使用前綴索引就沒啥意義,因為中國人名字都很短,另外對收件地址使用前綴索引也不是很實用,因為一方面收件地址一般都是以XX省開頭,也就是說前幾個字符都是差不多的,而且收件地址進行檢索一般都是like ’%xxx%’,不會用到前匹配。相反對外國人的姓名可以使用前綴索引,因為其字符較長,而且前幾個字符的選擇性比較高。同樣電子郵件也是一個可以使用前綴索引的字段。
- 前一半字符的索引選擇性就已經接近於全字段的索引選擇性。如果整個字段的長度為20,索引選擇性為0.9,而我們對前10個字符建立前綴索引其選擇性也只有0.5,那么我們需要繼續加大前綴字符的長度,但是這個時候前綴索引的優勢已經不明顯,沒有太大的建前綴索引的必要了。