1. 程式人生 > 資料庫 >MySQL字串索引更合理的建立規則討論

MySQL字串索引更合理的建立規則討論

前言

針對使用MySQL的索引,我們之前介紹過索引的最左字首規則,索引覆蓋,唯一索引和普通索引的使用以及優化器選擇索引等概念,今天我們討論下如何更合理的給字串建立索引。

如何更好的建立字串索引

我們知道,MySQL中,資料和索引都是在一顆 B+樹 上,我們建立索引的時候,這棵樹所佔用的空間越小,檢索速度就會越快,而varchar格式的字串有些會很長,那麼在效率為上的今天,我們如何更加合理的建立字串的索引呢?
假如說我們一張表中存在 email 欄位,現在要給 email 欄位建立索引,email 欄位值的格式為:[email protected]

有2種建立索引的方式:

1、直接給 email 欄位建立索引:alter table t add index index1(email);


索引樹結構為:

2、建立 email 的字首索引:alter table t add index index2(email(6));

索引資料結構為:

此時我們的查詢語句為:select id,name,email from t where email='[email protected]';

當使用index1索引時其執行步驟為:

1、從index1索引樹查詢索引值為[email protected]的主鍵值ID1;

2、根據ID1回表查到該行資料確實為[email protected],將結果加入結果集;

3、繼續查詢index1索引樹下一個索引值是否滿足[email protected],不滿足則結束查詢。

當使用index2索引時其執行步驟為:

1、從index2索引樹查詢索引值為zhangs的主鍵值ID1;

2、根據ID1回表查到該行資料確實為[email protected],將結果加入結果集;

3、 繼續查詢index2索引樹下一個索引值是否滿足zhangs,滿足則繼續回表查詢該行資料是否為[email protected],不是則跳過繼續查詢;

4、持續查詢index2索引樹,直到索引值不是zhangs為止。

從以上分析中我們可以看出,全欄位索引相比字首索引來說,減少了回表的次數,但是如果我們將字首從6個增加到7個8個的話,字首索引回表的次數就會減少,也就是說,只要定義好字首的長度,我們就能既節省空間又保證效率。

那麼問題來了,我們怎麼衡量使用字首索引的長度呢?

1、使用 select count(distinct email) as L from t; 查詢欄位不同值的個數;

2、依次選取不同的字首長度檢視不同值的個數:

select
 count(distinct left(email,4))as L4,count(distinct left(email,5))as L5,6))as L6,7))as L7,from t;

然後根據實際可接受的損失比例,選取適合的最短的字首長度。

字首的長度問題我們解決了,但是一個問題是,如果使用字首索引,那我們索引覆蓋的特性就用不到了。
用全欄位索引時,當我們查詢select id,email from t where email='[email protected]';時,不用回表直接就能查到id和email欄位。

但是用字首索引時,MySQL並不清楚字首是否會整個覆蓋email的值,無論是否全包含都會根據主鍵值回表查詢判斷。

所以說,使用字首索引雖然能節省空間保證效率但是卻不能用到覆蓋索引的特性,是否使用就在於具體考慮了。

其他字串索引建立方式

實際情況實際考慮,並不是所有的字串都能使用字首擷取的方式建立索引,如身份證號或者ip這些字串使用字首索引就不合理了,身份證號一般同一個地區的人前幾位都是一模一樣的,使用字首索引就不合理了,而ip值我們一般在實際中將其轉化為數字去儲存。

針對身份證號,我們可以使用倒敘儲存,取字首建立索引或者使用crc32()函式來獲取一個hash校驗碼(int值)當做索引。

倒敘:select field_list from t where id_card = reverse('input_id_card_string');

crc32:select field_list from t where id_card_crc=crc32('input_id_card_string') and id_card='input_id_card_string'

這兩種方式相對來說效率都差不多,都不支援範圍查詢,支援等值查詢。

在倒敘方式中,需要使用reverse函式,但是回表次數可能比hash方式多。

在hash方式中,需要新建一個索引欄位並呼叫crc32()函式。(注意:crc32()函式獲取的結果不保證能唯一,可能存在重複的情況,但是這種情況概率較小),回表次數少,幾乎1次就行。

最後

針對字串索引,一般有以下幾種建立方式:

1、字串較短,直接全欄位索引

2、字串較長,且字首區分度較好,建立字首索引

3、字串較長,字首區分度不好,倒敘或hash方式建立索引(這種方式範圍查詢就不行了)

4、根據實際情況,遇到特殊字串,特殊對待,如ip。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對我們的支援。