高效能索引

weixin_33850890發表於2018-07-01

寫在前面:
索引的三個優點:

  1. 索引大大減少了伺服器需要掃描的資料量
  2. 索引可以幫助伺服器避免排序和臨時表
  3. 索引可以將隨機 I/O 變為順序 I/O
  • 索引一般分為:
    主鍵索引:不能為空 不能重複
    普通索引
    create index 索引名稱 on 表名(列名,)
    drop index 索引名稱 on 表名
    唯一索引:不能重複
    create unique index 索引名稱 on 表名(列名)
    drop unique index 索引名稱 on 表名
    聯合(組合)索引
    create unique index 索引名稱 on 表名(列名,列名)
    drop unique index 索引名稱 on 表名
    如果有組合索引,注意最左字首匹配,從最左邊開始匹配
    注意索引合併只是配合兩個單獨的索引而已。
    組合索引效率 > 索引合併效率

高效能索引策略

  • 獨立的列
    指的是索引列不能是表示式的一部分,也不能是函式的引數
    不好的索引
    select actor_id from sakila.actor where actor_id+1 = 5
    我們應該簡化 where 條件,始終將索引列單獨放在比較符號的一側。
    不好的又一個示例:
    select ... where to_days(current_date) - to_days(date_col) <= 10

  • 字首索引和索引選擇性
    有時候需要索引很長的字元列,一個策略是模擬雜湊索引,還有一個策略是:通常可以索引開始的部分字元,但這會降低索引的選擇性。
    索引的選擇性:不重複的索引值和資料表的記錄總數的比值,索引的選擇性越高查詢效率越高。唯一索引的選擇性是1,這是最好的索引選擇性,效能也是最好的。
    對於 BLOB,TEXT 或很長的 varchar 型別列,必須使用字首索引。
    缺點:MySQL 無法使用字首索引做 order by 和 group by,也無法使用字首索引做覆蓋掃描。
    當然也可以創造字尾索引,只需將字串反向儲存即可。

  • 多列索引
    通常“把 where 條件裡面的列都建上索引”這樣模糊的建議是錯誤的,在多個列上建立獨立的單列索引大部分情況並不能提高 MySQL 的查詢效能。有時可以優化索引列的順序。

  • 選擇合適的索引列順序

  • 雜湊值少的不適合建索引
    如性別

  • 聚簇索引
    這是一種資料儲存方式。表資料按照索引的順序來儲存的,也就是說索引項的順序與表中記錄的物理順序一致。對於聚集索引,葉子結點即儲存了真實的資料行,不再有另外單獨的資料頁。
    非聚簇索引
    表資料儲存順序與索引順序無關。對於非聚集索引,葉結點包含索引欄位值及指向資料頁資料行的邏輯指標,其行數量與資料錶行資料量一致。

  • 覆蓋索引
    在索引檔案中直接找到資料,只是一個名詞,不是真實的索引

  • 使用索引掃描來做排序

  • 壓縮(字首壓縮)索引
    MyISAM 使用字首壓縮來減少索引的大小。

  • 冗餘和重複索引
    例如在 primary key 列上又建立 unique ,通常沒有必要。
    還有建立了索引(A,B),再建立(A)就是冗餘索引,因為它是 (A,B)的字首索引。但(B,A),(B)就不是了。

  • 未使用的索引
    有一些索引永遠不會被使用。建議刪除。
    以下幾種情況不會命中索引:
    like 使用函式, or,型別不一致 != > order by
    or 可能會出現沒法走索引,但如果 where 索引1=xxx or field=xxx and 索引2=xxx 它就會走索引
    用 order by 的時候,注意取 order by 欄位,否則不會走索引。一般主鍵都有特殊性,對於 != < > 會走索引。

相關文章