避免索引失效的一些原則

2021-10-03 08:17:28 字數 2341 閱讀 1060

宣告:本文中的所有案例都在mysql5.7版本下進行實踐

索引在資料庫優化上提供了很大的幫助,了解一些常見的索引失效原則,對sql優化會有很大的幫助

1、首先復合索引遵循最佳左字首匹配原則,即,如果有乙個復合索引順序為(a1,a2,a3),則在使用時,必須要使用上a1列索引,才能使用上a2列索引,如果a1列索引失效了,a2,a3都會失效。復合索引不要跨列使用或者無序使用

2、復合索引,盡量使用全索引匹配,即,如果建立了(a1,a2,a3)復合索引,則盡量將a1,a2,a3三列都使用上

準備資料,建立一張book表,字段如下所示

create table book

( bid int(4) primary key,

name varchar(20) not null,

authorid int(4) not null,

publicid int(4) not null,

typeid int(4) not null

);

執行查詢語句:查詢authorid=1且typeid為2或3的 bid欄位,按照typeid降序,sql語句explain如下

下面我們對這條sql語句進行優化,加上索引。我們觀察到,sql中使用到了bid,typeid,authorid列,所以我們建立乙個復合索引,包含著三列,但是復合索引的順序應該是怎麼樣的呢?可以這樣嗎(bid,typeid,authorid)? 這樣是錯的,在sql語句中雖然編寫的時候bid在最前面,但是實際解析的時候,應該是先解析where子句,然後在解析select語句的,所以索引的順序應該是(typeid,authorid,bid),建立好索引我們再次執行上面的sql。發現使用到了索引,並且長度為12

那麼現在就是最優的了嗎?不一定,在where子句中,typeid欄位使用到了in關鍵字,而這個關鍵字可能會讓索引失效,一旦typeid列的索引失效了,等於沒有使用上索引(參照復合索引的最佳左字首原則) 

所以我們可以這樣子,將typeid欄位和authorid欄位換一下位置,將原來的復合索引刪掉,建立新順序的復合索引(authorid,typeid,bid),這樣子,即使typeid列的索引失效了,我們也可以使用到authorid列的索引,因為現在是authorid列在前面

小結:最佳左字首,保持索引的定義和使用的順序一致性

索引需要逐步優化

將含in的範圍查詢 放到where條件的最後,防止失效

現在我們在book表中,只有(typeid,authorid,bid)順序的復合索引

執行下面的sql,由於authorid欄位使用了乘法,所以只使用了typeid列的索引,故key_len=4

執行以下sql,由於在typeid欄位上使用了乘法,所以復合索引直接全部失效(最佳左字首),故key的值為null

現在我們在book表中,只有(typeid,authorid,bid)順序的復合索引

執行以下sql,因為我們在typeid列上使用了!=,導致復合索引失效

在book表的name欄位建立單值索引

alter table book add index name_index(name);

執行以下sql,name欄位的型別是varchar,而我們卻寫name=123,讓name進行了一次型別轉換,所以索引失效。

在book表中現在有三個索引,name列的單值索引,bid列的主鍵索引,(typeid,authorid,bid)復合索引

執行以下sql,我們使用了or關鍵字,導致索引全部失效

我們學習索引優化 ,是乙個大部分情況適用的結論,但由於sql優化器等原因  會導致該結論不是100%正確。

mysql學習(五)避免索引失效的一些原則

a.復合索引,不要跨列使用或無序使用 遵循最佳左字首 b.復合索引盡量使用全索引匹配 2.不要在索引上進行任何操作 計算 函式 型別轉換 否則索引失效 select where a.x 假設a.x是索引 不要 select where a.x 3 explain select from book w...

新建索引的一些原則

1 表的主鍵 外來鍵必須有索引 2 資料量超過300的表應該有索引 3 經常與其他表進行連線的表,在連線欄位上應該建立索引 4 經常出現在where子句中的字段,特別是大表的字段,應該建立索引 5 索引應該建在選擇性高的字段上 6 索引應該建在小字段上,對於大的文字字段甚至超長字段,不要建索引 7 ...

導致索引失效的一些情況

1 隱式轉換導致索引失效.這一點應當引起重視.也是開發中經常會犯的錯誤.由於表的字段tu mdn定義為varchar2 20 但在查詢時把該字段作為number型別以where條件傳給oracle,這樣會導致索引失效.錯誤的例子 select from test where tu mdn 13333...