MySQL編程 優化篇(二) SQL優化(ⅱ)索引問題

目錄

 

索引的分類

能夠使用索引的典型場景

存在索引但不能使用索引的典型場景


索引的分類

  • B-Tree索引:最常見的索引類型,大部分引擎都支持B樹索引

  • HASH索引:只有Memory引擎支持,使用場景簡單

  • R-Tree索引(空間索引):空間索引是MyISAM的一個特殊索引類型,主要用於地理空間數據類型,通常使用較少,不做特別介紹

  • Full-text(全文索引):全文索引也是 MyISAM 的一個特殊索引類型,主要用於全文索引,InnoDB從MySQL 5.6版本開始提供對全文索引的支持。

  • MySQL目前不支持函數索引,但是能對列的前面某一部分進行索引(前綴索引);缺點,在排序Order By和分組Group By操作的時候無法使用

能夠使用索引的典型場景

如有複合索引:(a, b)

  1. 匹配全值(Match the full value),對索引中所有列都指定具體值,即是對索引中的所有列都有等值匹配的條件,如:a = xx AND b = xx。

  2. 匹配值的範圍查詢(Match a range of values),對索引的值能夠進行範圍查找,如:a > 1 AND a < 10。

  3. 匹配最左前綴(Match a leftmost prefix),僅僅使用索引中的最左邊列進行查找,比如在 col1 + col2 + col3 字段上的聯合索引能夠被包含 col1、(col1 + col2)、(col1 + col2 + col3)的等值查詢利用到,可是不能夠被 col2、(col2 + col3)的等值查詢利用到。

  4. 僅僅對索引進行查詢(Index only query),當查詢的列都是索引的字段中時,查詢的效率更高,即:避免使用select *,最好使用select a,b ...,即查詢的列都是索引列,不需要回表查數據

  5. 匹配列前綴(Match a column prefix),僅僅使用索引中的第一列,並且只包含索引第一列的開頭一部分進行查找,即: like 'a%'

  6. 能夠實現索引匹配部分精確而其他部分進行範圍匹配(Match one part exactly and match a range on another part),如:a = ‘x’ AND b > 1AND b < 2

  7. 如果列名是索引,那麼使用 column_name is null就會使用索引(區別於Oracle)

  8. MySQL 5.6引入了 Index Condition Pushdown(ICP)的特性,進一步優化了查詢。Pushdown表示操作下放,某些情況下的條件過濾操作下放到存儲引擎。Explain Extra:Using index condition就表示MySQL使用了 ICP 來進一步優化查詢。

 

補充:Index Condition Pushdown(ICP),將customer_id的過濾操作下推到存儲引擎層來完成,這樣能夠降低不必要的IO訪問

存在索引但不能使用索引的典型場景

  1. 以%開頭的LIKE查詢不能夠利用B-Tree索引,執行計劃中key的值爲NULL表示沒有使用索引

  2. 數據類型出現隱式轉換的時候也不會使用索引

  3. 複合索引的情況下,假如查詢條件不包含索引列最左邊部分,即不滿足最左原則Leftmost,是不會使用複合索引的

  4. 如果 MySQL 估計使用索引比全表掃描更慢,則不使用索引。在查詢的時候,篩選性越高越容易使用到索引,篩選性越低越不容易使用索引。

  5. 用or分割開的條件,如果or前的條件中的列有索引,而後面的列中沒有索引,那麼涉及的索引都不會被用到

發佈了74 篇原創文章 · 獲贊 132 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章