最近作一些項目接口的優化工做,發現其中涉及到調整mysql語句的方面,接口速度是提高最高的,藉機學習一下關於mysql索引方面的知識mysql
基本是 《高性能MYSQL》的第五章 - 《建立高性能索引》的閱讀sql
以前關於索引的錯誤理解bash
建表以後把字段都設置爲索引比較好服務器
只要建立了索引並使用這個字段,就能命中索引markdown
索引(在 MySQL 中也叫「鍵key」)是存儲引擎快速找到記錄的一種數據結構數據結構
因此能夠把索引看作一本書的目錄函數
mysql的索引是存儲引擎決定的,分爲B-tree索引和 哈希索引(hash index)性能
不一樣的存儲引擎對支持不一樣的兩種索引mysql索引
ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='xxx表' 複製代碼
咱們的項目中,存儲引擎是 InnoDB , 它使用的是 B-tree 索引,因此本文只是按照Btree來分享學習
減小服務器的掃描量
幫助服務器避免排序和臨時表
隨機IO變爲順序IO
三星原則:一星: 索引將相關的記錄放到一塊兒 二星:索引的數據順序和查找的順序一致 三星:索引的列包含查詢中須要的所有列
獨立的列: 不能是表達式的一部分,也不能是函數的參數
例: 篩選 area 字段是 beijing/beiJing/BeiJing 的數據
area已經在表裏添加了索引
select * from TABLE where Upper(area) = 'BEIJING' 複製代碼
若是是用函數處理了area字段
explain select * from TABLE where Upper(area) = 'BEIJING' 複製代碼
能夠看到是沒法命中索引的
把where中的字段都設置爲索引是最好的操做
其實這種狀況下,可能達到了一星索引標準,比最優的索引差了不少
因此在須要對多個索引作相交操做(OR)/聯合操做(AND) 的時候,能夠考慮建立聯合索引
這個是我的感受比較迷惑的一點,就是建立了聯合索引以後,若是sql語句中的字段順序與定義的不一致,那麼有可能也沒法使用索引
好比使用id和status定義複合索引
index (`id`,`status`)
複製代碼
那麼一下幾種sql語句 並非都能使用索引的
select * from T where status = '23' // 索引失效 select * from T where id > 123 and status = '23' // 索引部分失效 複製代碼
這個就是索引中的最左匹配原則
最左匹配原則: 索引首先按照最左列進行排序,其次第二列等等。因此索引可按照升序或者降序進行掃描,用以知足符合列順序的order by / group by等查詢需求
若有索引(a, b, c, d),查詢條件a = 1 and b = 2 and c > 3 and d = 4,則會在每一個節點依次命中a、b、c,沒法命中d
複製代碼
頻繁更新的字段
數據分佈比較均勻的,好比,性別字段
表數據量少