1. 什麼是索引?mysql
索引是一種數據結構,能夠幫助咱們快速的進行數據的查找.sql
2. 索引是個什麼樣的數據結構呢?數據結構
索引的數據結構和具體存儲引擎的實現有關, 在MySQL中使用較多的索引有Hash索引,B+樹索引等,而咱們常用的InnoDB存儲引擎的默認索引實現爲:B+樹索引.函數
3. Hash索引和B+樹全部有什麼區別或者說優劣呢?性能
首先要知道Hash索引和B+樹索引的底層實現原理:優化
hash索引底層就是hash表,進行查找時,調用一次hash函數就能夠獲取到相應的鍵值,以後進行回表查詢得到實際數據.B+樹底層實現是多路平衡查找樹.對於每一次的查詢都是從根節點出發,查找到葉子節點方能夠得到所查鍵值,而後根據查詢判斷是否須要回表查詢數據.code
那麼能夠看出他們有如下的不一樣:排序
由於在hash索引中通過hash函數創建索引以後,索引的順序與原順序沒法保持一致,不能支持範圍查詢.而B+樹的的全部節點皆遵循(左節點小於父節點,右節點大於父節點,多叉樹也相似),自然支持範圍.索引
hash索引不支持使用索引進行排序,原理同上.字符串
hash索引不支持模糊查詢以及多列索引的最左前綴匹配.原理也是由於hash函數的不可預測.AAAA和AAAAB的索引沒有相關性.
hash索引任什麼時候候都避免不了回表查詢數據,而B+樹在符合某些條件(聚簇索引,覆蓋索引等)的時候能夠只經過索引完成查詢.
hash索引雖然在等值查詢上較快,可是不穩定.性能不可預測,當某個鍵值存在大量重複的時候,發生hash碰撞,此時效率可能極差.而B+樹的查詢效率比較穩定,對於全部的查詢都是從根節點到葉子節點,且樹的高度較低.
所以,在大多數狀況下,直接選擇B+樹索引能夠得到穩定且較好的查詢速度.而不須要使用hash索引.
4. 上面提到了B+樹在知足聚簇索引和覆蓋索引的時候不須要回表查詢數據,什麼是聚簇索引?
在B+樹的索引中,葉子節點可能存儲了當前的key值,也可能存儲了當前的key值以及整行的數據,這就是聚簇索引和非聚簇索引. 在InnoDB中,只有主鍵索引是聚簇索引,若是沒有主鍵,則挑選一個惟一鍵創建聚簇索引.若是沒有惟一鍵,則隱式的生成一個鍵來創建聚簇索引.
當查詢使用聚簇索引時,在對應的葉子節點,能夠獲取到整行數據,所以不用再次進行回表查詢.
5. 非聚簇索引必定會回表查詢嗎?
不必定,這涉及到查詢語句所要求的字段是否所有命中了索引,若是所有命中了索引,那麼就沒必要再進行回表查詢.
舉個簡單的例子,假設咱們在員工表的年齡上創建了索引,那麼當進行select age from employee where age < 20
的查詢時,在索引的葉子節點上,已經包含了age信息,不會再次進行回表查詢.
6. 在創建索引的時候,都有哪些須要考慮的因素呢?
創建索引的時候通常要考慮到字段的使用頻率,常常做爲條件進行查詢的字段比較適合.若是須要創建聯合索引的話,還須要考慮聯合索引中的順序.此外也要考慮其餘方面,好比防止過多的全部對錶形成太大的壓力.這些都和實際的表結構以及查詢方式有關.
7. 聯合索引是什麼?爲何須要注意聯合索引中的順序?
MySQL可使用多個字段同時創建一個索引,叫作聯合索引.在聯合索引中,若是想要命中索引,須要按照創建索引時的字段順序挨個使用,不然沒法命中索引.
具體緣由爲:
MySQL使用索引時須要索引有序,假設如今創建了"name,age,school"的聯合索引,那麼索引的排序爲: 先按照name排序,若是name相同,則按照age排序,若是age的值也相等,則按照school進行排序.
當進行查詢時,此時索引僅僅按照name嚴格有序,所以必須首先使用name字段進行等值查詢,以後對於匹配到的列而言,其按照age字段嚴格有序,此時可使用age字段用作索引查找,,,以此類推.所以在創建聯合索引的時候應該注意索引列的順序,通常狀況下,將查詢需求頻繁或者字段選擇性高的列放在前面.此外能夠根據特例的查詢或者表結構進行單獨的調整.
8. 建立的索引有沒有被使用到?或者說怎麼才能夠知道這條語句運行很慢的緣由?
MySQL提供了explain命令來查看語句的執行計劃,MySQL在執行某個語句以前,會將該語句過一遍查詢優化器,以後會拿到對語句的分析,也就是執行計劃,其中包含了許多信息. 能夠經過其中和索引有關的信息來分析是否命中了索引,例如possilbe_key,key,key_len等字段,分別說明了此語句可能會使用的索引,實際使用的索引以及使用的索引長度.
9. 那麼在哪些狀況下會發生針對該列建立了索引可是在查詢的時候並無使用呢?