mysql 7 字串字段索引的優化

2021-10-04 21:03:14 字數 2594 閱讀 6053

對於字串字段建立索引,欄位越長那麼這個字段索引樹占用的磁碟空間就越大,相同的資料頁能放下的索引值就越少,搜尋的效率也就會越低。而且伴隨著表資料量的不斷增大,會導致這顆索引樹占用磁碟空間最後會非常大。這就需要我們根據實際業務場景來優化這個字串欄位的索引了。

字首索引

例如現在有張員工表:

mysql>

create

table t_staff(

id bigint

unsigned

primary

key,

email varchar(64

),-- 10位員工工號@shenzhenxx.com

username varchar(10

),password varchar(16

)...

)engine

=innodb

;

郵箱格式:10位員工工號@shenzhenxx.com

然後需要用郵箱進行登入操作,所以我們一般會選擇email欄位建立索引,來加快查詢效率。

建立索引我們可以如下兩種方式建立。

alter

table t_staff add

index idx_email1(email);或者

alter

table t_staff add

index idx_email2(email(10)

);

第乙個語句建立的 idx_email1索引裡面,包含了每個記錄的整個字串;而第二個語句建立的 idx_email2索引裡面,對於每個記錄都是只取前 10個位元組。

優缺點:

這兩種不同的定義在資料結構和儲存上是不一樣的,由於 email(10)這個索引結構中每個郵箱欄位都只取前 10 個位元組(即:10位工號)。

所以占用的空間會更小,這就是使用字首索引的優勢。所以當我們如果需要考慮節省磁碟空間時候,我們可以使用字首索引的方式來進行優化。

使用字首索引就用不上覆蓋索引對查詢效能的優化了(缺點),這也是你在選擇是否使用字首索引時需要考慮的乙個因素。

對於字首區分度不高的情況,建立字首索引是不合適的。例如,下表中的id_card身份證號字段

create

table

user

(id bigint

unsigned

primary

key,

id_card varchar(64

),--身份證號

name varchar(32

))

例如我們建立乙個idx_id_card(id_card(6))這樣乙個字首索引,然後執行下面查詢語句:

select id,id_card,name   from

user

where id_card=

'421123199910111234'

對於這個查詢的執行流程是:

idx_id_card索引樹找到滿足索引值是421123的記錄,然後找到第乙個id(葉子節點儲存主鍵值);

回表,到主鍵上查到主鍵值是 這個id 的行,判斷出 id_card的值是不是421123199910111234。不是,這行記錄丟棄;是,將這行記錄加入結果集。

重複上一步,直到在idx_id_card上取到的值不是421123時,迴圈結束

結論:在這樣的乙個執行流程下,大家可以想一下,由於字首區分度不高,字首是421123值非常多,最後導致乙個簡單的查詢語句,需要不停回表查詢,非常影響效率。所以這個時候建立字首索引是不合適的。

那麼我們有其他方法解決嘛?當然是有的,使用 hash 字段

hash欄位

你可以在表上再建立乙個整數字段,來儲存身份證的校驗碼,同時在這個欄位上建立索引。

alter

table

user

add id_card_crc int

unsigned

,add

index

(id_card_crc)

;

然後每次插入新記錄的時候,都同時用 crc32() 這個函式得到校驗碼填到這個新字段。由於校驗碼可能存在衝突,也就是說兩個不同的身份證號通過 crc32() 函式得到的結果可能是相同的,所以你的查詢語句 where 部分要判斷 id_card 的值是否精確相同。

select field_list from t where id_card_crc=crc32(

'input_id_card_string'

)and id_card=

'input_id_card_string'

這樣,索引的長度變成了 4 個位元組,比原來小了很多。算然多增加了乙個字段,但是從整體上看,還是節約了儲存的消耗。

7 字串比對

題目內容 題目說起來很簡單,你會讀到兩個字串,每個字串佔據一行,每個字串的長度均小於10000字元,而且第乙個字串的長度小於第二個字串的。你的程式要找出第乙個字串在第二個字串中出現的位置,輸出這些位置,如果找不到,則輸出 1。注意,第乙個字元的位置是0。注意,第乙個字串在第二個字串中的位置可能不止一...

1065 字串的索引對

題目描述 給出 字串 text 和 字串列表 words,返回所有的索引對 i,j 使得在索引對範圍內的子字串 text i text j 包括 i 和 j 屬於字串列表 words。示例 1 輸入 text thestoryofleetcodeandme words story fleet lee...

No7 字串匹配

注意 string類中已提供了字串匹配的api,現模擬該api實現 自定義子串查詢 string有自己的api str.indexof 0 param a 源串 param b 目的串 param index 從該引數開始查詢 return private static int findsubstr...