11 | 怎么給字符串字段加索引?

維護(hù)郵箱登錄系統(tǒng)贰锁,用戶表

mysql> select? f1, f2 from SUser where?email='xxx';? ? email 沒有索引巷屿,全表掃描固以。

創(chuàng)建索引的語(yǔ)句不指定前綴長(zhǎng)度,索引就會(huì)包含整個(gè)字符串。

mysql> alter? table SUser add index index1(email);? ? ? ? ? //含整個(gè)字符串

mysql> alter? table SUser add index index2(email(6));? ? ? //只取前 6 個(gè)字節(jié)

數(shù)據(jù)結(jié)構(gòu)和存儲(chǔ)區(qū)別

圖 1 email 索引結(jié)構(gòu)
圖 2 email(6) 索引結(jié)構(gòu)

一憨琳、前綴索引

占用空間小诫钓,可能會(huì)增加額外的記錄掃描次數(shù)。

select? id,name,email from SUser where email='zhangssxyz@xxx.com';

index1執(zhí)行順序:

1.? 從 index1 索引樹找到滿足索引值是’zhangssxyz@xxx.com’的這條記錄篙螟,取得 ID2 的值菌湃;

2.? 查主鍵值=ID2 行,?email 值正確遍略,行記錄加入結(jié)果集惧所;

3.? 取 index1 索引樹上剛剛查到的位置的下一條記錄,發(fā)現(xiàn)已經(jīng)不滿足email='zhangssxyz@xxx.com’的條件了绪杏,循環(huán)結(jié)束下愈。

回主鍵索引取一次,系統(tǒng)認(rèn)為掃描一行蕾久。

index2執(zhí)行順序:

1.? 從 index2 索引樹找到滿足索引值是’zhangs’的記錄势似,找到第一個(gè) ID1

2.? 查到主鍵=ID1 行腔彰,查出 email 的值不是’zhangssxyz@xxx.com’丟棄叫编;

3.? index2 下一條,這次值對(duì)了霹抛,加入結(jié)果集搓逾;

4. 重復(fù)上一步,idxe2 不是’zhangs’時(shí)杯拐,循環(huán)結(jié)束霞篡。

回主鍵索引取 4 次數(shù)據(jù)(index2要回索引),掃描了 4 行端逼。導(dǎo)致查詢次數(shù)多朗兵。

如果定義index2 不是 email(6) 而是 email(7),前綴’zhangss’只有一個(gè)顶滩,直接查到 ID2余掖。

前綴索引,定義好長(zhǎng)度礁鲁,節(jié)省空間盐欺,不用增加太多查詢成本。

二仅醇、多長(zhǎng)前綴好

建立索引時(shí)關(guān)注區(qū)分度冗美,區(qū)分度越高,重復(fù)鍵值越少析二。多少個(gè)不同的值粉洼,判斷用多長(zhǎng)前綴:

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

選取不同長(zhǎng)度的前綴來(lái)看這個(gè)值节预,看 4~7 個(gè)字節(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;

前綴索引很可能會(huì)損失區(qū)分度,設(shè)定可以接受的損失比例属韧,比如 5%安拟。 L4~L7 中,找出不小于 L * 95% 值挫剑,假設(shè)L6去扣、L7 都滿足,選擇前綴長(zhǎng)度為 6樊破。

三愉棱、前綴索引對(duì)覆蓋索引的影響

增加掃描行數(shù),不止影響性能哲戚。

select id,email? from SUser where email='zhangssxyz@xxx.com';? 只返回 id 和 email 字段奔滑。

用 index1可用覆蓋索引,直接返回顺少,不回ID 索引朋其。index2( email(6) )的話,回 ID 索引脆炎,再判斷 email 字段值梅猿。系統(tǒng)并不確定是否截?cái)嗤暾畔ⅰ?/p>

前綴索引就用不上覆蓋索引對(duì)查詢性能的優(yōu)化

郵箱效果不錯(cuò)。但公民信息系統(tǒng)秒裕,身份證號(hào)12 以上前綴索引袱蚓,滿足區(qū)分度

占用空間越大几蜻,數(shù)據(jù)頁(yè)索引值就越少喇潘,搜索效率越低。

四梭稚、占用空間小颖低,效率高

4.1 倒序存儲(chǔ)

身份證號(hào)倒過來(lái)存,每次查詢的時(shí)候:

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

最后 6 位弧烤。不要忘記用count(distinct)驗(yàn)證忱屑。

4.2 hash 字段

創(chuàng)建整數(shù)字段,保存身份證校驗(yàn)碼(創(chuàng)建索引)暇昂。

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

插入同時(shí)用 crc32()函數(shù)得到校驗(yàn)碼填到新字段想幻。可能存在沖突话浇,不同身份證號(hào) crc32() 結(jié)果相同,where 判斷 id_card 值是否精確相同闹究。

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

索引長(zhǎng)度4 字節(jié)幔崖,比原來(lái)小。

相同:

不支持范圍查詢。倒序存儲(chǔ)的字段上創(chuàng)建的索引是按照倒序字符串的方式排序的赏寇,已經(jīng)沒有辦法利用索引方式查出身份證號(hào)碼在 [ID_X, ID_Y]的所有市民了吉嫩。hash 只支持等值查詢。

區(qū)別:

1. 占用額外空間:倒序:存儲(chǔ)主鍵索引上嗅定,不消耗額外空間自娩, hash 增加一個(gè)字段。倒序存儲(chǔ)方式 4 字節(jié)不夠渠退,消耗差不多抵消忙迁。

2. CPU 消耗:倒序:寫和讀的時(shí)候,額外調(diào)用reverse 函數(shù)碎乃,hashcrc32() 函數(shù)姊扔。reverse 消耗 CPU 資源小。

3. 查詢效率梅誓,hash 穩(wěn)定恰梢,沖突概率小。倒序存儲(chǔ):前綴索引的方式梗掰,增加掃描行數(shù)嵌言。

小結(jié)

字符串字段創(chuàng)建索引場(chǎng)景,使用方式:

1.? 完整索引及穗,占用空間摧茴;

2.? 前綴索引,節(jié)省空間拥坛,增加查詢掃描次數(shù)蓬蝶,不能用覆蓋索引;

3.? 倒序存儲(chǔ)猜惋,再創(chuàng)建前綴索引丸氛,用于繞過字符串本身前綴的區(qū)分度不夠問題;

4.? hash 字段索引著摔,查詢性能穩(wěn)定缓窜,有額外存儲(chǔ)、計(jì)算消耗谍咆,不支持范圍掃描(跟第三種一樣)禾锤。

問題

維護(hù)學(xué)生信息數(shù)據(jù)庫(kù),登錄名”學(xué)號(hào) @gmail.com",學(xué)號(hào):15位數(shù)字摹察,城市編號(hào)(3)恩掷、學(xué)校編號(hào)(4、6)供嚎、入學(xué)年份(1~10)黄娘、順序編號(hào)(后5)峭状。

只考慮登錄驗(yàn)證,怎么設(shè)計(jì)登錄名索引逼争?

正优床、反向,重復(fù)度都高誓焦。入學(xué)年份+順序編號(hào)(9)

在此基礎(chǔ)上胆敞,數(shù)字類型存。201100001杂伟,占 4 個(gè)字節(jié)移层。就是一種 hash,字符串轉(zhuǎn)數(shù)字

評(píng)論1

學(xué)校每年預(yù)估2萬(wàn)新生稿壁,50年才100萬(wàn)記錄幽钢,直接全字段索引

hash索引適合,登錄檢驗(yàn)傅是,不需范圍查詢匪燕。倒序索引,區(qū)分度沒前綴高喧笔。

評(píng)論2

學(xué)號(hào)用bigint存儲(chǔ),4個(gè)字節(jié)帽驯,比前綴索引占用要小。比hash索引书闸,有區(qū)間查詢的優(yōu)勢(shì)

評(píng)論3

表數(shù)據(jù)量特別大:

字符串字段進(jìn)制壓縮尼变,限制每個(gè)字符范圍(如字母數(shù)字下劃線)。

每個(gè)字節(jié)并沒存8 bit信息量浆劲。單個(gè)字符取值只有n種可能性(把字符轉(zhuǎn)成0到n-1的數(shù)字)嫌术,把n進(jìn)制轉(zhuǎn)為為更高進(jìn)制存儲(chǔ)(ascii可看做是128進(jìn)制)。

減少索引長(zhǎng)度牌借,兼顧前綴匹配

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末度气,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子膨报,更是在濱河造成了極大的恐慌磷籍,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件现柠,死亡現(xiàn)場(chǎng)離奇詭異院领,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)够吩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門比然,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人周循,你說我怎么就攤上這事谈秫“羌模” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵拟烫,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我迄本,道長(zhǎng)硕淑,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任嘉赎,我火速辦了婚禮置媳,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘公条。我一直安慰自己拇囊,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布靶橱。 她就那樣靜靜地躺著寥袭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪关霸。 梳的紋絲不亂的頭發(fā)上传黄,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音队寇,去河邊找鬼膘掰。 笑死,一個(gè)胖子當(dāng)著我的面吹牛佳遣,可吹牛的內(nèi)容都是我干的识埋。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼零渐,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼窒舟!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起相恃,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤辜纲,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后拦耐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體耕腾,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年杀糯,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了扫俺。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡固翰,死狀恐怖狼纬,靈堂內(nèi)的尸體忽然破棺而出羹呵,到底是詐尸還是另有隱情,我是刑警寧澤疗琉,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布冈欢,位于F島的核電站,受9級(jí)特大地震影響盈简,放射性物質(zhì)發(fā)生泄漏凑耻。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一柠贤、第九天 我趴在偏房一處隱蔽的房頂上張望香浩。 院中可真熱鬧,春花似錦臼勉、人聲如沸邻吭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)囱晴。三九已至,卻和暖如春猖败,著一層夾襖步出監(jiān)牢的瞬間速缆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工恩闻, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留艺糜,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓幢尚,卻偏偏與公主長(zhǎng)得像破停,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子尉剩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容