閱讀本文大概需要 4 分鐘。
一、前言
在 MySQL 中進行 SQL 優化的時候,經常會在一些情況下,對 MySQL 能否利用索引有一些迷惑。例如:
MySQL 在遇到範圍查詢條件的時候就停止匹配了,那麼到底是哪些範圍條件?
MySQL 在 LIKE 進行模糊匹配的時候又是如何利用索引的呢?
MySQL 到底在怎麼樣的情況下能夠利用索引進行排序?
今天,我將會用一個模型,把這些問題都一一解答,讓你對 MySQL 索引的使用機制有進一步的瞭解。
二、知識補充
key_len
EXPLAIN 執行計劃中有一列 key_len 用於表示本次查詢中,所選擇的索引長度有多少字節,通常我們可藉此判斷聯合索引有多少列被選擇了。
在這裏 key_len 大小的計算規則是:
一般地,key_len 等於索引列類型字節長度,例如 int 類型爲4 bytes,bigint 爲 8 bytes;
如果是字符串類型,還需要同時考慮字符集因素,例如:CHAR(30) UTF8 則 key_len 至少是 90 bytes;
若該列類型定義時允許 NULL,其 key_len 還需要再加 1 bytes;
若該列類型爲變長類型,例如 VARCHAR(TEXT\BLOB 不允許整列創建索引,如果創建部分索引也被視爲動態列類型),其 key_len 還需要再加 2 bytes;
三、哪些條件能用到索引
首先非常感謝登博,給了我一個很好的啓發,我通過他的文章,然後結合自己的理解,製作出了這幅圖:
乍一看,是不是很暈,不急,我們慢慢來看圖中一共分了三個部分:
Index Key:MySQL 是用來確定掃描的數據範圍,實際就是可以利用到的 MySQL 索引部分,體現在 Key Length。
Index Filter:MySQL 用來確定哪些數據是可以用索引去過濾,在啓用 ICP 後,可以用上索引的部分。
Table Filter:MySQL 無法用索引過濾,回表取回行數據後,到 server 層進行數據過濾。我們細細展開。
Index Key
Index Key 是用來確定 MySQL 的掃描範圍,分爲上邊界和下邊界。
MySQL 利用=、>=、> 來確定下邊界(first key),利用最左原則,首先判斷第一個索引鍵值在 where 條件中是否存在,如果存在,則判斷比較符號,如果爲 (=,>=) 中的一種,加入下邊界的界定,然後繼續判斷下一個索引鍵,如果存在且是 (>),則將該鍵值加入到下邊界的界定,停止匹配下一個索引鍵;
如果不存在,直接停止下邊界匹配。
舉個