1. 怎麼給字符串字段加索引?
-
案例:給郵箱加索引
-- 普通索引,包含了每個記錄的整個字符串; alter table User add index index1(email); -- 前綴索引,對於每個記錄都是隻取前 6 個字節 ALTER TABLE User ADD INDEX index2(email(6));
-
前綴索引:
- 優點:佔用空間比較小
- 缺點:會增加額外的掃描次數
-
執行以下SQL
select id,name,email from SUser where email='[email protected]';
- 使用index1:
1. 從index1索引樹上尋找滿足條件的索引值[email protected]
的記錄主鍵爲ID2
2. 到主鍵上去找主鍵值爲ID2的行,判斷email值是正確的,將這條記錄加入索引值
3. 取index1索引樹上剛剛查的的下一條記錄,發現不滿足條件,循環結束
4. 這個過程只向主鍵取了一次數據,所以系統認爲只掃描了一行 - 使用index2:
- 從index2索引樹上找滿足索引值
zhangs
的記錄,找到的第一個是ID1- 到主鍵找主鍵值ID1,判斷email,如果不是則丟棄,如果是則加入結果集
- 重複上一步i,知道
idnex2
上取到的值不是zhangs
時,循環結束 - 這個過程,向主鍵取了4次數據,掃描了4行
- 重複上一步i,知道
- 到主鍵找主鍵值ID1,判斷email,如果不是則丟棄,如果是則加入結果集
- 從index2索引樹上找滿足索引值
- 使用index1:
-
根據實際效果,使用前綴索引,要定義和長度,就可以做到既節省空間,有不用額外增多太多的查詢成本
-
怎麼才能確定我該使用多長的前綴呢?
-
關注區分度,區分度越高,意味着重複的值越少,索引要統計帶建立的索引上有多少不同的值,建議使用以下
SQL
取統計一下有多少個不同的值 -
使用前綴索引會損傷區分度,一般選擇不小於95%的比例
select count(distinct email) as L from SUser; -- 統計4-7個字節的前綴索引 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(eamil,7)) as L7 from SUer;
2. 前綴索引對覆蓋索引的影響
- 使用前綴索引就用不上覆蓋索引對查詢性能的優化了,這個也是在選擇是否使用前綴索引時需要考慮的一個因素】、
3. 區分度不大,怎麼利用前綴索引?
-
例如身份證號?
-
使用倒序存儲
-- 一般身份證號後6位不會重複 select field_list from t where id_card = reverse('input_id_card_string')
-
使用hash字段
--在表上創建一個整數字段,保存身份證號的校驗碼,同時在這個字段上創建索引 alter table t add id_card_crc int unsigned, add index (id_card_crc) -- 因爲crc32()函數,得到的結果可能重複,所以需要增加判斷 select field_list from t where id_card_crc = crc32('input_id_card_string') and id_card='input_id_card_string'
-
這兩種手段都不支持範圍查詢,
- 佔用空間:差不多,hash新增4個字節佔用的空間,而倒序存儲使用4個字節的前綴長度應該不夠,相互抵消
- cpu消耗: reverse相比較crc32()消耗資源小一些
- 查詢效率 : hash比較好,掃描結果解決1行
-