7.怎么給字符串字段加索引2022-02-20

mysql> alter table SUser add index index1(email);

mysql> alter table SUser add index index2(email(6));
我們知道,如果選擇給字符串加索引,那么索引的區(qū)分度會影響查詢效率,如果同一個索引值有N個相同的前綴,就會多次回表查詢,影響效率,所以怎么選擇索引長度呢?

一、如何選擇索引長度?

首先,你可以使用下面這個語句,算出這個列上有多少個不同的值:

mysql> select count(distinct email) as L from SUser;

然后,依次選取不同長度的前綴來看這個值,比如我們要看一下 4~7 個字節(jié)的前綴索引,可以用這個語句

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

當(dāng)然,使用前綴索引很可能會損失區(qū)分度,所以你需要預(yù)先設(shè)定一個可以接受的損失比例,比如 5%。然后,在返回的 L4~L7 中,找出不小于 L * 95% 的值,假設(shè)這里 L6、L7 都滿足,你就可以選擇前綴長度為 6。

二、用前綴索引就不能用覆蓋索引優(yōu)化了

因為系統(tǒng)并不確定前綴索引的定義是否截斷了完整信息,所以前綴索引就會回表。

三、其它方式加索引

1.倒序存儲

例子:比如你要創(chuàng)建以身份證為索引的查詢,因為身份證號在同一區(qū)縣的前幾位都是相同的,所以截取前幾位身份證為索引的區(qū)分度并不高。

mysql> select field_list from t where id_card = reverse('input_id_card_string');

2.使用hash字段

在表中新增一個字段,用于存儲hash( crc32() 這個函數(shù))身份證號后的值。crc32有四個字節(jié)。

mysql> alter table t add id_card_crc int unsigned, add index(id_card_crc);

因為可能存在hash沖突,所以要判斷身份證的全部值。

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

3.使用倒序前綴和hash的區(qū)別

相同點:因為都對原主鍵進(jìn)行處理,只適合等值查詢,不適合范圍查詢。
不同點:
(1)占用額外空間看,倒序不用新增字段,但是前綴長度可能超過hash的crc32函數(shù)的4個字節(jié),總體上差不多。
(2)cpu占用來看,倒序使用的reverse函數(shù)比crc32函數(shù)占用要少。
(3)查詢效率看,hash使用的crc32函數(shù)發(fā)生hash沖突的概率比前綴的區(qū)分度小發(fā)生回表查詢的概率要小。

三、思考題

如果你在維護(hù)一個學(xué)校的學(xué)生信息數(shù)據(jù)庫,學(xué)生登錄名的統(tǒng)一格式是”學(xué)號 @gmail.com", 而學(xué)號的規(guī)則是:十五位的數(shù)字,其中前三位是所在城市編號、第四到第六位是學(xué)校編號、第七位到第十位是入學(xué)年份、最后五位是順序編號。
系統(tǒng)登錄的時候都需要學(xué)生輸入登錄名和密碼,驗證正確后才能繼續(xù)使用系統(tǒng)。就只考慮登錄驗證這個行為的話,你會怎么設(shè)計這個登錄名的索引呢?

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容