切換語言為:簡體

MySQL索引失效常見的6種情況

  • 爱糖宝
  • 2024-09-25
  • 2048
  • 0
  • 0

開門見山

如果MySQL無法根據當前條件找出唯一的一條下潛路線或者索引有序性被破壞,此時索引失效(停止索引)

唯一的意思是僅有一條;找不到和找到好幾個都不屬於唯一

例子

常見的六種失效

MySQL索引失效常見的6種情況

MySQL索引以B+樹為基礎,在建立表時,InnoDB 儲存引擎預設會建立一個主鍵索引,也就是聚簇索引,其它索引都屬於二級索引。其中主鍵索引存放了資料,二級索引存放了主鍵,使用二級索引會產生回表操作

MySQL索引失效常見的6種情況

對索引使用左或者左右模糊匹配

對索引使用左模糊好理解

select * from t_user where name like '%林';

MySQL的字串比較是從左往右以此比較的,使用左模糊就意味著,只要是個以林為字尾的字串就符合要求小林1林2林等等;

而從B+樹的角度看,這些字串可能分佈在樹的各個位置被查詢資料是無序的,B+樹完全無法找到唯一的下潛路徑,不如直接全表掃描

對索引使用右模糊好

select * from t_user where name like '林%';

由上面可知,索引可以找到唯一的一條下潛路徑,直到最終定位到一個子樹上,這個子樹的name都是以開頭的;這時索引結束,直接移動到子節點上,轉為range

對索引使用函式

select * from t_user where length(name)=6;

我們的索引是以name的值為基礎建立的,在name層面是有序的,但在length(name)無法保證有序性,當前節點的左側和右側都有可能存在長度為6的字串,MySQL無法根據當前條件找出唯一的一條下潛路線

MySQL索引失效常見的6種情況

比如你站在h點,你會發現往左往右都對

被函式處理的數值,無法保證其有序性和原始數值相同

對索引進行表示式計算

select * from t_user where id + 1 = 10;

實際上這個例子不太好,因為只是簡單的 +1 並不影響原始的有序性,路徑也是唯一的,實際上從理論上是可以用索引的;在實際中表達式運算可能很複雜,以至於其y值可能解出多個x值;這時候x是不唯一的MySQL無法找到唯一的下潛路徑

更合適的例子

bash程式碼解讀複製程式碼select * from t_user where id*id = 4;

此時id = 2 or -2;此時你站在0點,你會發現往左往右都對

對索引隱式型別轉換

這一條涉及到MySQL的特性

MySQL 在遇到字串和數字比較的時候,會自動把字串轉為數字,然後再進行比較

  1. 當索引值為字串,條件是數字時;MySQL會去轉換索引值,此時類似於對索引使用函式;有序性被破壞,MySQL無法找出唯一的一條下潛路徑

  2. 當索引值為陣列,條件是字串時,被轉換的是條件,可以繼續走索引

聯合索引非最左匹配

在聯合索引的情況下,資料是按照索引第一列排序,第一列資料相同時纔會按照第二列排序。 也就是說,如果我們想使用聯合索引中儘可能多的列,查詢條件中的各個列必須是聯合索引中從最左邊開始連續的列。如果我們僅僅按照第二列搜尋,肯定無法走索引。

這個好理解,如果我們的索引是(a, b, c),但查詢條件是b or c or b and c;此時等同於不存在索引,MySQL當然也無法根據這些條件去找到唯一的下潛路徑

這裏還有個索引下推的知識點,當查詢條件為a and c時可以觸發

WHERE 對非索引列執行 or 運算

顯而易見,對非索引列執行查詢只能全表掃描;MySQL找不到索引路徑;

當然,如果兩個都是索引,MySQL可以分別索引,然後求並集;

總結

今天給大家介紹了 6 種會發生索引失效的情況:

  • 當我們使用左或者左右模糊匹配的時候,也就是 like %xx 或者 like %xx%這兩種方式都會造成索引失效;

  • 當我們在查詢條件中對索引列使用函式,就會導致索引失效。

  • 當我們在查詢條件中對索引列進行表示式計算,也是無法走索引的。

  • MySQL 在遇到字串和數字比較的時候,會自動把字串轉為數字,然後再進行比較。如果字串是索引列,而條件語句中的輸入引數是數字的話,那麼索引列會發生隱式型別轉換,由於隱式型別轉換是透過 CAST 函式實現的,等同於對索引列使用了函式,所以就會導致索引失效。

  • 聯合索引要能正確使用需要遵循最左匹配原則,也就是按照最左優先的方式進行索引的匹配,否則就會導致索引失效。

  • 在 WHERE 子句中,如果在 OR 前的條件列是索引列,而在 OR 後的條件列不是索引列,那麼索引會失效。

結尾見山

如果MySQL無法根據當前條件找出唯一的一條下潛路線或者索引有序性被破壞,此時索引失效(停止索引)

0則評論

您的電子郵件等資訊不會被公開,以下所有項目均必填

OK! You can skip this field.