通過不斷的縮小想要獲得資料的範圍來篩選出最終想要的結果,同時把隨機的事件變成順序的事件,也就是我們總是通過同一種查詢方式來鎖定資料。資料庫索引就是通過演算法提高查詢效率。
磁碟io與預讀:
考慮到磁碟io是非常高昂的操作,計算機作業系統做了一些優化,當一次io時,不光把當前磁碟位址的資料,而是把相鄰的資料也都讀取到記憶體緩衝區內,因為區域性預讀性原理告訴我們,當計算機訪問乙個位址的資料的時候,與其相鄰的資料也會很快被訪問到。每一次io讀取的資料我們稱之為一頁(page)。具體一頁有多大資料跟作業系統有關,一般為4k或8k,也就是我們讀取一頁內的資料時候,實際上才發生了一次io,這個理論對於索引的資料結構設計非常有幫助。
索引的資料結構:
@b+樹
每次查詢資料時把磁碟io次數控制在乙個很小的數量級,最好是常數數量級。那麼我們就想到如果乙個高度可控的多路搜尋樹是否能滿足需求呢?就這樣,b+樹應運而生。
1.最左字首匹配原則,非常重要的原則,mysql會一直向右匹配直到遇到範圍查詢(>、 3 and d = 4 如果建立(a,b,c,d)順序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引則都可以用到,a,b,d的順序可以任意調整。
2.=和in可以亂序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意順序,mysql的查詢優化器會幫你優化成索引可以識別的形式
3.盡量選擇區分度高的列作為索引,區分度的公式是count(distinct col)/count(*),表示欄位不重複的比例,比例越大我們掃瞄的記錄數越少,唯一鍵的區分度是1,而一些狀態、性別字段可能在大資料面前區分度就是0,那可能有人會問,這個比例有什麼經驗值嗎?使用場景不同,這個值也很難確定,一般需要join的字段我們都要求是0.1以上,即平均1條掃瞄10條記錄
4.索引列不能參與計算,保持列「乾淨」,比如from_unixtime(create_time) = 』2014-05-29』就不能使用到索引,原因很簡單,b+樹中存的都是資料表中的字段值,但進行檢索時,需要把所有元素都應用函式才能比較,顯然成本太大。所以語句應該寫成create_time = unix_timestamp(』2014-05-29』);
5.盡量的擴充套件索引,不要新建索引。比如表中已經有a的索引,現在要加(a,b)的索引,那麼只需要修改原來的索引即可
0.先執行看看是否真的很慢,注意設定sql_no_cache
1.where條件單錶查,鎖定最小返回記錄表。這句話的意思是把查詢語句的where都應用到表中返回的記錄數最小的表開始查起,單錶每個字段分別查詢,看哪個欄位的區分度最高
2.explain檢視執行計畫,是否與1預期一致(從鎖定記錄較少的表開始查詢)
3.order by limit 形式的sql語句讓排序的表優先查
4.了解業務方使用場景
5.加索引時參照建索引的幾大原則
6.觀察結果,不符合預期繼續從0分析
MySQL索引原理及慢查詢優化
2.和in可以亂序,比如a 1 and b 2 and c 3 建立 a,b,c 索引可以任意順序,mysql的查詢優化器會幫你優化成索引可以識別的形式。3.盡量選擇區分度高的列作為索引,區分度的公式是count distinct col count 表示欄位不重複的比例,比例越大我們掃瞄的記錄數越...
閱讀筆記 MySQL索引原理及慢查詢優化
讀文章弄清楚索引的資料結構b 樹及其查詢過程 1.最左字首匹配原則,非常重要的原則,mysql會一直向右匹配直到遇到範圍查詢 between like 就停止匹配,比如a 1 and b 2 and c 3 and d 4 如果建立 a,b,c,d 順序的索引,d是用不到索引的,如果建立 a,b,d...
MySQL索引原理與慢查詢優化
索引的目的在於提高查詢效率,可以模擬字典,如果要查 mysql 這個單詞,我們肯定需要定位到m字母,然後從下往下找到y字母,再找到剩下的sql。如果沒有索引,那麼你可能需要把所有單詞看一遍才能找到你想要的,如果我想找到m開頭的單詞呢?或者w開頭的單詞呢?是不是覺得如果沒有索引,這個事情根本無法完成?...