8.7 使用索引-notes
七 正確使用索引
一 索引未命中
并不是說我們創建了索引就一定會加快查詢速度,若想利用索引達到預想的提高查詢速度的效果,我們在添加索引時,必須遵循以下問題
1 范圍問題,或者說條件不明確,條件中出現這些符號或關鍵字:>、>=、<、<=、!= 、between...and...、like、
2 盡量選擇區分度高的列作為索引,區分度的公式是count(distinct col)/count(*),表示字段不重復的比例,比例越大我們掃描的記錄數越少,唯一鍵的區分度是1,而一些狀態、性別字段可能在大數據面前區分度就是0,那可能有人會問,這個比例有什么經驗值嗎?使用場景不同,這個值也很難確定,一般需要join的字段我們都要求是0.1以上,即平均1條掃描10條記錄
分析原因 我們編寫存儲過程為表s1批量添加記錄,name字段的值均為egon,也就是說name這個字段的區分度很低(gender字段也是一樣的,我們稍后再搭理它)回憶b+樹的結構,查詢的速度與樹的高度成反比,要想將樹的高低控制的很低,需要保證:在某一層內數據項均是按照從左到右,從小到大的順序依次排開,即左1<左2<左3<...而對于區分度低的字段,無法找到大小關系,因為值都是相等的,毫無疑問,還想要用b+樹存放這些等值的數據,只能增加樹的高度,字段的區分度越低,則樹的高度越高。極端的情況,索引字段的值都一樣,那么b+樹幾乎成了一根棍。本例中就是這種極端的情況,name字段所有的值均為'egon'#現在我們得出一個結論:為區分度低的字段建立索引,索引樹的高度會很高,然而這具體會帶來什么影響呢???#1:如果條件是name='xxxx',那么肯定是可以第一時間判斷出'xxxx'是不在索引樹中的(因為樹中所有的值均為'egon’),所以查詢速度很快#2:如果條件正好是name='egon',查詢時,我們永遠無法從樹的某個位置得到一個明確的范圍,只能往下找,往下找,往下找。。。這與全表掃描的IO次數沒有多大區別,所以速度很慢 分析原因3 =和in可以亂序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意順序,mysql的查詢優化器會幫你優化成索引可以識別的形式
4 索引列不能參與計算,保持列“干凈”,比如from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,原因很簡單,b+樹中存的都是數據表中的字段值,但進行檢索時,需要把所有元素都應用函數才能比較,顯然成本太大。所以語句應該寫成create_time = unix_timestamp(’2014-05-29’)
5 and/or
#1、and與or的邏輯條件1 and 條件2:所有條件都成立才算成立,但凡要有一個條件不成立則最終結果不成立條件1 or 條件2:只要有一個條件成立則最終結果就成立#2、and的工作原理條件:a = 10 and b = 'xxx' and c > 3 and d =4索引:制作聯合索引(d,a,b,c)工作原理:對于連續多個and:mysql會按照聯合索引,從左到右的順序找一個區分度高的索引字段(這樣便可以快速鎖定很小的范圍),加速查詢,即按照d—>a->b->c的順序#3、or的工作原理條件:a = 10 or b = 'xxx' or c > 3 or d =4索引:制作聯合索引(d,a,b,c)工作原理:對于連續多個or:mysql會按照條件的順序,從左到右依次判斷,即a->b->c->d6 最左前綴匹配原則(詳見第八小節),非常重要的原則,對于組合索引mysql會一直向右匹配直到遇到范圍查詢(>、<、between、like)就停止匹配(指的是范圍大了,有索引速度也慢),比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)順序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引則都可以用到,a,b,d的順序可以任意調整。
十 慢查詢優化的基本步驟
0.先運行看看是否真的很慢,注意設置SQL_NO_CACHE 1.where條件單表查,鎖定最小返回記錄表。這句話的意思是把查詢語句的where都應用到表中返回的記錄數最小的表開始查起,單表每個字段分別查詢,看哪個字段的區分度最高 2.explain查看執行計劃,是否與1預期一致(從鎖定記錄較少的表開始查詢) 3.order by limit 形式的sql語句讓排序的表優先查 4.了解業務方使用場景 5.加索引時參照建索引的幾大原則 6.觀察結果,不符合預期繼續從0分析總結
以上是生活随笔為你收集整理的8.7 使用索引-notes的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Docker 与 DevOps自动化部署
- 下一篇: Django 的cookie 与 ses