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