關於 MySQL 索引的一些認識

悲劇不上演發表於2017-11-30

最近由於公司的業務量增加需要給先有資料庫增加索引,查詢網上資料庫,學習了一番,特來分享!

  • MYSQL索引型別:

    1. 普通索引(normal)
      這是最基本的索引,它沒有任何限制
      CREATE INDEX indexName ON mytable(username(length));
      如果是CHAR,VARCHAR型別,length可以小於欄位實際長度;如果是BLOB和TEXT型別,必須指定 length,下同。
    2. 唯一索引(unique)
      它與前面的普通索引類似,不同的就是:索引列的值必須唯一,但允許有空值。如果是組合索引,則列值的組合必須唯一。
      CREATE UNIQUE INDEX indexName ON mytable(username(length))
    3. 全文索引(full textl)
      全文搜尋的索引,用於搜尋很長一篇文章的時候,效果最好。用在比較短的文字,如果就一兩行字的,普通索引可以。
      CREATE FULLTEXT INDEX indexName ON mytable(username)

      總結,索引的類別由建立索引的欄位內容特性來決定,通常normal最常見。

  • 建立索引:

    前言:給欄位建立索引之前一定想一下該欄位的區分度,根據區分度的大小,也能大概知道在該欄位上的新建索引是否有效,以及效果如何。區分度越大,索引效果越明顯。區分度SQL語句:select count(distinct(username))/count(*) from mytable;根據該SQL可知:區分度值位於0.000~1.000之間,該值越大即該欄位的區分度越大!

    1. 建立單列索引:
      可以檢視該欄位的區分度,根據區分度的大小,也能大概知道在該欄位上的新建索引是否有效,以及效果如何。區分度越大,索引效果越明顯。
    2. 建立多列索引:

      多列索引中其實還有一個欄位的先後順序問題,一般是將區分度較高的放在前面,這樣聯合索引才更有效。

      eg:select * from t_base_user where name='' and status=1;應該增加 idx_name_status(name,status);而不是idx_status_name(status,name)

      最左字首匹配原則:和where後面的順序無關

      eg:當我們建立的索引為index(type,created_at,status)。這個根據最左字首原則其實是建立了3個索引分別為index(type),index(type,created_at),index(type,created_at,status)。 以下三個SQL都會走index(type,created_at,status)這個索引,
      SQL1:select * from t_base_user where type=10 and created_at='2017-11-03' and status=1
      SQL2:select * from t_base_user where type=10 and status=1 and created_at='2017-11-03'
      SQL3:select * from t_base_user where created_at='2017-11-03' and status=1 and type=10

      因為mysql查詢優化器會判斷糾正這條sql語句該以什麼樣的順序執行效率最高,最後才生成真正的執行計劃。所以,當然是我們能儘量的利用到索引時的查詢順序效率最高咯,所以mysql查詢優化器會最終以這種順序進行查詢執行。

Last::mysql會選擇一個最嚴格(獲得結果集記錄數最少)的索引,意思也就是隻會走一個索引
第一次寫了個分享,耗時比較長不太會排版,請各位包含,如有不對請指正:bowtie:

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章