避免索引失效原則(一)


避免索引失效的一些原則

我們編寫SQL語句后會進行添加一些索引進行優化,但是有時候確實建了索引,但索引有時候會失效

比如在模糊查詢使用 in 關鍵字的時候索引就失效了,這只是其中的一個條件;

1.復合索引的時候,不要跨列或無序使用(最佳左前綴)

我在前幾篇文章有重點介紹過;

就比如你建立了一個索引 分別字段為 a b c,你使用的時候卻沒有從a開始向后依次使用,而是使用了a c 把中間的b漏掉了下面我舉個例子:

比如我 where a ...  and b ...  order by c,這種使用順序就符合最佳做前綴,我從左向右依次使用了索引,如果你寫成下面這樣:

where b ... and a order by c,這樣很明顯你順序不對,並不滿足最佳左前綴,從而導致了索引失效;

2.復合索引,盡量使用全索引匹配

假設我現在建立了一個復合索引 a b c,在查詢的時候,盡量把這些索引字段都用上;

比如我現在想找一個張三,你先根據 a 找,再根據b找,最后再根據c找,這樣找就會更快一點,盡量不要你建了三個索引你卻只用兩個,這樣雖然可以,但是卻把一級目錄給刪了;

就跟看書一樣,我要找書上一個精確內容,准確來說先看目錄,再看章節,再看最后的小結,道理是一樣的;

3.不要在索引上進行任何操作

如果你在索引上進行任何操作,索引就必將失效,什么是任何操作,下發我將舉例說明:

比如你對索引進行加減乘除計算,進行一些函數計算,或進行一些類型轉換,在這種情況下,索引都會失效;

比如我select ... where A.x = ...;簡單寫一個這樣的就行了,不要再進行一些花里胡哨的操作,這里假設A.x是索引

你不要寫成:select... where A.x*3 = ....;即是是索引,你算完之后就失效了,就不要這樣干!

這里就給大家演示一下:我現在編寫一條SQL語句記得前面加explain:

select * from book where authroid = 1 and typeid = 2;

首先book表中的 authroid 跟 typeid 均是索引:

通過key_len可以清楚的發現我用到了兩個索引一個是四,兩個加起來就是八,這兩個索引本別是authroid  typeid ,而且查詢效率是ref級別,接下來我就對它進行一些操作;

explain select * from book where authroid = 1 and typeid*2 = 2;

執行結果:

雖然我們的查詢級別仍然是ref,但是值得注意的是,key_len變成了四,我明明寫了兩個索引,現在卻少了一個,明明有兩個索引,你卻用了一個,原因很簡單,因為我在typeid上進行乘法操作了!

如果還不能明白,我這次把這兩個索引字段都進行操作

explain select * from book where authroid*2 = 1 and typeid*2 = 2;

執行結果:

這個結果夠明顯了把,查詢級別變成了ALL,而且我明明有兩個索引,卻一個都沒有用!所以從這里面就能得出結論,不能對索引進行任何操作,否則就會導致索引失效!

4.對於復合索引左邊失效右邊全部失效

現在我們對上一條SQL語句再進行更改操作:

select * from book where authroid*2 = 1 and typeid = 2;

這條SQL語句authroid typeid 這兩個字段是復合索引,我現在給authroid字段進行操作,下面我們看執行結果:

我即便沒有對typid進行任何操作,但是導致的結果卻是全部失效

原因很簡單,在復合索引下,你左前第一個失效,那么你后面全部跟着失效;

假設有 a b c 這些字段是復合索引,我給a 字段進行乘法操作,那么b c 字段都將會失效;

給b加字段,b后面的全部字段都會失效,a不受影響;

這里值得一提的是,如果有兩個復合索引,比如 a1 a2是一個復合索引,b1 b2也是一個復合索引,即便a1在左邊a1失效了a2會跟着失效但是b1 b2不受影響,因為復合索引與復合索引之間是沒有任何關系的;

5.復合索引不能使用不等於(!= 或 <> is null (is not null))

如果用以上其中一種,會導致資深以及右側索引全部失效,下面我將會舉例說明:

我現在編寫一條SQL語句j記得前面加上explain 

select * from book where authoid = 1 and typeid = 2

其中authoid typeid 均是復合索引:

執行結果發現一些異常現象,首先key里面只生效了一個,在key_len里面是4不是8,因為我用了兩個索引應該是8才對我也沒有對索引進行操作,但就是失效了一個;

原因:SQL優化是一種概率層面的優化,至於是否實際使用了我們的優化,需要通過explaini進行推測,在possible_keys中我們可以看到,它預測使用了兩個索引,但實際它就是只用了一個,因為MySQL優化是概率的,即便你手動優化的很少,有時你照樣正常生效,這正常現象,因為手動優化試只是概率;

現在我們不管概率問題,我們繼續緊接着上剛才的例子;

我們看到authroid仍在生效,我們這次把authroid進行一些不等於操作

explain  select * from book where authoid ! = 1 and typeid = 2

執行結果:

奇怪的事情又發生了,這次查詢級別仍是fef但是我們發現authoid確實失效了但是typeid生效了

原來authoid失效只是你自身失效了,並不影響其他字段的生效概率,也可以理解為typeid把authoid給干掉了!

那么接下來我都給他加上不等於試試:

explain  select * from book where authoid ! = 1 and typeid ! = 2;

執行結果:

這里我就不再過多闡述了,很顯然,全部失效了

今日感悟:

年輕人:“我有很多好的想法”

智者:“想和做,是兩種截然不同的境界,不要把自己“想做”一件事情誤會成自己“在做”一件事情”

智者:“另外,不要把“在做”一件事,誤會成“做成”一件事”


免責聲明!

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



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