爲何你建立的數據庫索引沒有生效?

幾乎全部的小夥伴均可以隨口說幾句關於建立索引的優缺點,也知道何時建立索引可以提升咱們的查詢性能,何時索引會更新,可是你有沒有注意到,即便你設置了索引,有些時候索引他是不會生效的!這不只考察了你們對索引的瞭解程度,還要讓你們在使用的時候可以正確的使用。如下介紹了一些可能會形成索引失效的特殊狀況,但願你們在平時開發和麪試的時候可以注意到!html

1、如何判斷數據庫索引是否生效
首先在接着探討以前,咱們先說一下,如何判斷數據庫的索引是否生效!相信你們應該猜到了,就是explain!explain顯示了MySQL如何使用索引來處理select語句以及鏈接表。他能夠幫助選擇更好的索引和寫出更優化的查詢語句。mysql

例如咱們有一張表user,爲name列建立索引name_index,以下所示:  面試

 

使用explain分析語句以下:sql

 

能夠看到,使用explain顯示了不少列,各個關鍵字的含義以下:數據庫

table:顧名思義,顯示這一行的數據是關於哪張表的;後端

type:這是重要的列,顯示鏈接使用了何種類型。從最好到最差的鏈接類型爲:const、eq_reg、ref、range、indexhe和ALL;函數

possible_keys:顯示可能應用在這張表中的索引。若是爲空,沒有可能的索引。能夠爲相關的域從where語句中選擇一個合適的語句;性能

key: 實際使用的索引。若是爲NULL,則沒有使用索引。不多的狀況下,MySQL會選擇優化不足的索引。這種狀況下,能夠在Select語句中使用USE INDEX(indexname)來強制使用一個索引或者用IGNORE INDEX(indexname)來強制MySQL忽略索引;優化

key_len:使用的索引的長度。在不損失精確性的狀況下,長度越短越好;.net

ref:顯示索引的哪一列被使用了,若是可能的話,是一個常數;

rows:MySQL認爲必須檢查的用來返回請求數據的行數;

Extra:關於MySQL如何解析查詢的額外信息。

具體的各個列所能表示的值以及含義能夠參考MySQL官方文檔介紹,地址:https://dev.mysql.com/doc/refman/5.7/en/explain-output.html

2、哪些場景會形成索引生效
一、應儘可能避免在 where 子句中使用 != 或 <> 操做符,不然引擎將放棄使用索引而進行全表掃描;

 

二、儘可能避免在 where 子句中使用 or 來鏈接條件,不然將致使引擎放棄使用索引而進行全表掃描,即便其中有條件帶索引也不會使用,這也是爲何儘可能少用 or 的緣由;

 

三、對於多列索引,不是使用的第一部分,則不會使用索引;

四、若是列類型是字符串,那必定要在條件中將數據使用引號引用起來,不然不會使用索引;

 

五、like的模糊查詢以 % 開頭,索引失效;

 

六、應儘可能避免在 where 子句中對字段進行表達式操做,這將致使引擎放棄使用索引而進行全表掃描;

 

七、應儘可能避免在 where 子句中對字段進行函數操做,這將致使引擎放棄使用索引而進行全表掃描;

 

八、不要在 where 子句中的 「=」 左邊進行函數、算術運算或其餘表達式運算,不然系統將可能沒法正確使用索引;

九、若是MySQL估計使用全表掃描要比使用索引快,則不使用索引;

十、不適合鍵值較少的列(重複數據較多的列)

假如索引列TYPE有5個鍵值,若是有1萬條數據,那麼 WHERE TYPE = 1將訪問表中的2000個數據塊。再加上訪問索引塊,一共要訪問大於200個的數據塊。若是全表掃描,假設10條數據一個數據塊,那麼只需訪問1000個數據塊,既然全表掃描訪問的數據塊少一些,確定就不會利用索引了。

相關文章
相關標籤/搜索