如何檢查sql語句的條件字段是否使用了索引以及索引失效的幾種情況


今天執行通過時間范圍查詢訂單數量的sql時,想看看該時間字段是否走了索引,發現一個很有意思的問題.

首先說一下查詢是否使用了索引的方法

通過explain來查看,即將explain放在查詢的sql前面

explain SELECT * from ord_order_consume where create_time > '2020-04-01 00:00:00' and create_time < '2020-07-23 23:59:59'

 查詢結果

 

 主要說明一下紅框里邊字段的含義

table: sql所查詢的表名

type: 結果值從好到壞依次是:

system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL

一般來說,得保證查詢至少達到range級別,最好能達到ref,否則就可能會出現性能問題

possible_keys: sql可能用到的索引

key: sql實際用到的索引,如果是Null,說明沒有用到索引

rows: MySQL認為執行查詢時必須檢查的行數

 

這里有一個有意思的問題,那就是其實我的表里邊create_time字段是加了索引的,但可以看到type=ALL,說明沒有使用到索引,這是為什么呢?

開始我以為是< >符號的問題,因為我看一篇博客上說,sql語句使用< >符號,會導致全部搜索,於是我改用between...and...語法

explain SELECT * from ord_order_consume where create_time between '2020-04-01 00:00:00' and '2020-07-23 23:59:59'

查詢結果

 

 發現type仍然是ALL,沒有使用索引,說明這里跟< >符號沒有關系

但是,當我將日期范圍調小之后

explain SELECT * from ord_order_consume where create_time > '2020-06-01 00:00:00' and create_time < '2020-07-23 23:59:59'

查詢結果

 

 發現type變為了range,並且key也有索引的名稱,說明使用了索引

由此得出結論

當時間類型的字段存在索引時,索引是否使用與查詢到的數量大小有關

查詢到的數量大,不使用索引;

查詢到的數量小,使用索引;

至於這個數量是什么范圍,好像是有一個比例.不過我大致測了一下,如果查詢結果在兩萬左右,會使用索引,再大就不再使用索引了(這里僅做參考)

 

那么,導致sql語句跳過索引,直接全表搜索的情況還有哪些呢?這里簡單做個總結

1.where條件查詢語句帶or,只要帶or,即使其中的查詢條件包含有索引的字段,也會導致索引失效,除非查詢條件的字段都帶索引(注意:主鍵自帶索引,屬於唯一索引的特定類型)

explain select * from ord_order_consume where user_id = 1349813 or buss_type = 2

結果

2.對於復合索引,如果查詢條件不是第一個索引字段,那么不會使用索引

explain select * from ord_order_consume where create_time = '2020-06-01 00:00:00'

結果

 

 

explain select * from ord_order_consume where order_state = 20

結果

3.like模糊查詢,%在左邊(查了不少資料,說%在右邊不會導致索引失效,但我實踐了一下,發現也失效了,具體原因有待進一步研究)

explain select * from ord_order_consume where stake_no like '%1'

結果

 

 

4.where查詢條件字段如果是varchar類型,必須用引號引起來,否則索引失效

explain select * from ord_order_consume where stake_no  = 1140290000001466

 

 

 select * from ord_order_consume where stake_no = '1140290000001466'

 

5.索引字段上使用 != 或者 <> 不等於操作符時,索引失效

EXPLAIN SELECT * from user where age != 18

 

EXPLAIN SELECT * from user where age <> 18

EXPLAIN SELECT * from user where age > 17 or age < 19

 

6.in  和 not in 會導致索引失效

EXPLAIN SELECT * from user where age in (18,19)

 

EXPLAIN SELECT * from user where age not in (18,19)

 

7.where查詢字段進行表達式操作,索引失效

EXPLAIN SELECT * from user where age/2 = 10

 

 

EXPLAIN SELECT * from user where age = 10*2

 

 

8.where查詢字段進行函數式操作,索引失效 

EXPLAIN SELECT * from user where substring(name,1,1) = '張'

 

 

9.當全表掃描速度比索引速度快時,Mysql會使用全表掃描,此時索引失效

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM