mysql怎麼給字符串字段加索引?

1. 怎麼給字符串字段加索引?

  1. 案例:給郵箱加索引

    -- 普通索引,包含了每個記錄的整個字符串;
    alter table User add index index1(email);    
    -- 前綴索引,對於每個記錄都是隻取前 6 個字節
    ALTER TABLE User ADD INDEX index2(email(6)); 
    
  2. 前綴索引:

    1. 優點:佔用空間比較小
    2. 缺點:會增加額外的掃描次數
  3. 執行以下SQL

       select id,name,email from SUser where email='[email protected]';
    
    • 使用index1:
      ​ 1. 從index1索引樹上尋找滿足條件的索引值 [email protected]的記錄主鍵爲ID2
      ​ 2. 到主鍵上去找主鍵值爲ID2的行,判斷email值是正確的,將這條記錄加入索引值
      ​ 3. 取index1索引樹上剛剛查的的下一條記錄,發現不滿足條件,循環結束
      ​ 4. 這個過程只向主鍵取了一次數據,所以系統認爲只掃描了一行
    • 使用index2:
      1. 從index2索引樹上找滿足索引值zhangs的記錄,找到的第一個是ID1
        1. 到主鍵找主鍵值ID1,判斷email,如果不是則丟棄,如果是則加入結果集
          1. 重複上一步i,知道idnex2上取到的值不是 zhangs時,循環結束
          2. 這個過程,向主鍵取了4次數據,掃描了4行
  4. 根據實際效果,使用前綴索引,要定義和長度,就可以做到既節省空間,有不用額外增多太多的查詢成本

    1. 怎麼才能確定我該使用多長的前綴呢?

    2. 關注區分度,區分度越高,意味着重複的值越少,索引要統計帶建立的索引上有多少不同的值,建議使用以下SQL取統計一下有多少個不同的值

    3. 使用前綴索引會損傷區分度,一般選擇不小於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. 前綴索引對覆蓋索引的影響

    1. 使用前綴索引就用不上覆蓋索引對查詢性能的優化了,這個也是在選擇是否使用前綴索引時需要考慮的一個因素】、

    3. 區分度不大,怎麼利用前綴索引?

    1. 例如身份證號?

    2. 使用倒序存儲

      -- 一般身份證號後6位不會重複
      select field_list from t where id_card = reverse('input_id_card_string')
      
    3. 使用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'
      
    4. 這兩種手段都不支持範圍查詢,

      • 佔用空間:差不多,hash新增4個字節佔用的空間,而倒序存儲使用4個字節的前綴長度應該不夠,相互抵消
      • cpu消耗: reverse相比較crc32()消耗資源小一些
      • 查詢效率 : hash比較好,掃描結果解決1行
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章