天天看點

【MySQL系列】- LIKE查詢 以%開頭一定會讓索引失效嗎

前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。​​點選跳轉到網站。​​

MySQL查詢導緻索引失效的情況有很多,通過搜尋引擎搜尋MySQL索引失效 幾乎都會提到一個情況,那就是like查詢以“%”開頭。但是 LIKE查詢 以%開頭一定會讓索引失效嗎?

【MySQL系列】- LIKE查詢 以%開頭一定會讓索引失效嗎

驗證準備

  1. 建立一張users表,表結構如下,表中有999999條資料:
【MySQL系列】- LIKE查詢 以%開頭一定會讓索引失效嗎
  1. 在name字段上建立索引
【MySQL系列】- LIKE查詢 以%開頭一定會讓索引失效嗎

驗證階段

要驗證一段SQL語句有沒有使用到索引,最好的方法莫過于使用SQL執行計劃EXPLAIN了。

  • 首先先看一下LIKE查詢不以%開頭的情況:
EXPLAIN SELECT  * FROM users WHERE `name` LIKE '001%';      
【MySQL系列】- LIKE查詢 以%開頭一定會讓索引失效嗎

type=range,key=idx_name,說明這段是使用了索引的。

  • 接着再看一下LIKE查詢不以%開頭的情況

    先看第一段SQL語句:

EXPLAIN SELECT * FROM users WHERE `name` LIKE '%001%'      
【MySQL系列】- LIKE查詢 以%開頭一定會讓索引失效嗎

type=ALL,是以這段SQL是沒有使用索引的。

再來看第二段SQL語句:

EXPLAIN SELECT  `name` FROM users WHERE `name` LIKE '%001%';      
【MySQL系列】- LIKE查詢 以%開頭一定會讓索引失效嗎

type=index,key=idx_name,這個結果說明這段SQL是使用了索引的。

接着看第三段SQL語句:

EXPLAIN SELECT  id , `name` FROM users WHERE `name` LIKE '%001%';      
【MySQL系列】- LIKE查詢 以%開頭一定會讓索引失效嗎

第三段SQL語句是在第二段SQL語句的基礎上多查詢一列id。這個執行結果和第二段是一樣的,說明這段也是使用了索引的。

最後看一下第四段SQL語句:

EXPLAIN SELECT  id , `name` , gender FROM users WHERE `name` LIKE '%001%';      
【MySQL系列】- LIKE查詢 以%開頭一定會讓索引失效嗎

第四段SQL語句是在第三段SQL語句的基礎上多查詢兩列id和gender。執行結果和第一段一樣,是沒有使用索引的。

驗證結果

通過以上驗證可以發現,LIKE查詢 以%開頭不一定會讓索引失效。

為什麼會走索引呢?

首先解釋一下,執行計劃中type=ALL和index。還有key的含義。

  • type=ALL:全表掃描,周遊整張表去查詢比對的結果,不走索引。
  • type=index:使用索引覆寫,僅僅掃描索引樹,比ALL要快。
  • type=range:使用索引進行範圍查詢時就會用到range通路方法。
  • key:實際使用到的索引,如果為NULL就是沒使用索引。

LIKE查詢以%開頭使用了索引的原因就是使用了索引覆寫。

針對二級索引MySQL提供了一個優化技術。即從輔助索引中就可以得到查詢的記錄,就不需要回表再根據聚集索引查詢一次完整記錄。使用索引覆寫的一個好處是輔助索引不包含整行記錄的所有資訊,故其大小要遠小于聚集索引,是以可以減少大量的IO操作,但是前提是要查詢的所有列必須都加了索引。

LIKE查詢以%開頭會導緻全索引掃描或者全表掃描,如果沒有索引覆寫的話,查詢到的資料會回表,多了一次IO操作,當MySQL預估全表掃描或全索引掃描的時間比走索引花費的時間更少時,就不會走索引。有了索引覆寫就不需要回表了,減少了IO操作,花費的時間更少,是以就使用了索引。

總結