本文主要介紹MySQL 中關於索引的一些問題,例如:索引的做用;怎麼建立索引;設計索引的原則;怎麼優化索引等等。數據庫
一:索引概述性能
索引通常是經過排序,而後查找時能夠二分查找,這一特色來達到加速查找的目的的。優化
全部的MySQL列類型都能建立索引,良好設計的因此可以很好地提升查詢的性能,但若是索引過多,因爲每次更新操做都會對索引進行更新,反而會影響到數據庫的總體性能。於是,遵循必定的原則,設計合適的索引是很是重要的。spa
(1):建立索引的語法設計
CREATE [UNIQUE|FULLTEXT|SPQTIAL] INDEX index_name [USING index_type] ON table_name(col_name)指針
例子:建了一張user表,有屬性 name, age, address, 下面圖能夠看出沒創建索引和創建索引時查詢的區別。blog
二:設計索引的幾個原則排序
(1): where子句中的列比select中的列更適合作索引。索引
(2): 選擇那些基數大的列,這要的索引效果更好,這要索引才能很好地區分不一樣值。字符串
(3): 使用短索引,例如一個char(200)的列,若是前20個字符就能很好的區分不一樣的值時,就不必對整個列進行索引,這樣能夠大大的減小索引的存儲空間。
(4): 不要過分索引,只創建所需的索引。過多的索引會浪費磁盤空間,下降寫的性能,也會給查詢優化帶來更多的工做,讓MySQL選擇不到最好的索引。
(5): InnoDB儘可能本身指定主鍵:InnoDB 引擎存儲的表會按照必定的順序保存,例如主鍵,惟一索引,若是都沒有則會自動生成一個內部列,按照這些進行訪問是最快的,因此InnoDB儘可能本身指定主鍵。當有多個列能夠做爲主鍵時,選擇最常做爲訪問條件的列做爲主鍵。
例子:InnoDB沒建立索引,但創建了主鍵,會用主鍵進行查詢。
三:BTREE索引和HASH索引
MyISAM 和 InnoDB 默認建立的是BTREE索引,MEMORY引擎默認建立的是Hash索引,BTREE 用於全值匹配,匹配列前綴,範圍匹配時很是有效。HASH索引存儲的是hash值,而且是全部索引列的Hash值,只能用於精確匹配。
BTREE 的幾個限制:
(1). 必須按照索引的最左列開始查找
(2). 不能跳過索引中的列
(3). 某個列使用了範圍查詢,其右邊的列都沒法使用索引。
索引列的位置順序,很是重要,寫SQL時須要尤爲注意。
HASH索引的幾個限制:
(1). hash索引只存儲哈希值和行指針,不存儲字段值,結構緊湊。
(2). 數據不是按照索引值順序存儲的,因此沒法用於排序。
(3). 不支持部分索引列的匹配查找,由於hash值是用全部的索引列計算的。
(4). 只支持精確查找
四:索引的優化
在遵循索引的設計原則後,設計索引和編寫SQL時還須要注意索引使用時的幾個特色:
(1). 前綴特性 : 當建立了多列索引時,只要用到了前面的列,索引就會起做用。例如建立了兩列索引(a,b) ,當where條件語句中僅出現了a,索引也會被使用,但僅僅出現了b,索引將不會被使用。
(2). 使用like查詢時,%不能出如今第一個字符,應該是 「 常量 + %」,這樣索引纔可能會起做用。
(3). 對大文本進行搜索時,使用全文索引而不是使用 like '%...%, 更好的方法是在BTREE的基礎上創建僞Hash索引,僅僅須要對這列計算hash值再存儲,能夠節省空間。缺陷是須要維護hash值,能夠用觸發器維護。
(4). 用or分割開的條件,若是or前面的列有索引,後面的列沒有索引,那麼涉及到索引都不會被用到。
(5). 若是列類型是字符串,記得where條件中把字符串常量值用引號引發來。
查看索引的使用狀況,用 show status like 'Handle_read%' 查看Handle_read_key(值大說明索引獲得了很好的使用,反之亦然) 和 Handle_read_rnd_next(值很大說明進行了大量的全盤掃描,索引沒獲得很好地使用) 的值。