MySQL索引原理及查詢優化

2021-10-01 19:17:26 字數 2232 閱讀 7995

其實在工作中有去優化mysql語句,但之前優化僅僅是降到能夠接受花費時間之下,並有很多可以繼續提供的空間。很多時候在優化完成之後sql,也並不能向外展示。故這裡將自己平時優化的sql方法記錄下來,並找到乙個總結優化sql的地方。

索引原理

mysql的建立索引其實就像是字典的目錄有一定的相似之處,通過不斷的縮小想要獲得資料的範圍來篩選出最終想要的結果。我們索引原理可以通過了解為什麼資料庫的索引需要使用b+樹,來了解索引的原理。

mysql的資料儲存在磁碟之中,mysql的獲取資料需要將mysql中資料讀取到記憶體之中,這個過程可以叫io,這段時間需要耗費的時間是比較大的。當計算機訪問乙個位址的資料的時候,與其相鄰的資料也會很快被訪問到。每一次io讀取的資料我們稱之為一頁(page),具體一頁有多大資料跟作業系統有關,一般為4k或8k。如果沒有索引,mysql就需要去讀去整個資料庫裡面的內容。我們經常接觸到查詢資料結構一般有 二叉樹、平衡二叉樹、紅黑樹、再到b-樹、b+樹、雜湊索引。

為什麼從這些結構選擇了b+樹作為mysql的索引結構呢?對比二叉樹、平衡二叉樹、紅黑樹 ,b+樹的子節點更少,這樣可以縮小整個樹的高度,這樣可以縮小io讀取的資料的次數,判斷的次數更小。對於b-樹相對於b+資料,b-tree因為非葉子結點也儲存具體資料,所以在查詢某個關鍵字的時候找到即可返回。而b+tree所有的資料都在葉子結點,每次查詢都得到葉子結點。所以在同樣高度的b-tree和b+tree中,b-tree查詢某個關鍵字的效率更高。但由於b+tree所有的資料都在葉子結點,並且結點之間有指標連線,在找大於某個關鍵字或者小於某個關鍵字的資料的時候,b+tree只需要找到該關鍵字然後沿著鍊錶遍歷就可以了,而b-tree還需要遍歷該關鍵字結點的根結點去搜尋。更重要的是由於b-tree的每個結點(這裡的結點可以理解為乙個資料頁)都儲存主鍵+實際資料,而b+tree非葉子結點只儲存關鍵字資訊,而每個頁的大小有限是有限的,所以同一頁能儲存的b-tree的資料會比b+tree儲存的更少。這樣同樣總量的資料,b-tree的深度會更大,增大查詢時的磁碟i/o次數,進而影響查詢效率。hash索引在不存在hash碰撞的情況下,之需一次讀取,查詢複雜度為o(1),比b+樹快。但hash只能用於等值查詢,不能用於範圍查詢。並且b+資料葉子節點的資料是連線在一起的,而hash資料是更加散亂,我們在獲取資料的時候基本都是一批資料。所以hash也並不適用。

我們在對優化sql的時候,對mysql的索引有個大概印象就可以,並不需要了解非常深入。

sql優化步驟

1、先執行看看是否真的很慢,注意設定sql_no_cache。

2、explain檢視執行計畫,特別需要注意是否連線查詢中很多rows很大的值。

(rows很大,很多是必要的子查詢、連線查詢的對索引字段進行的操作、從鎖定記錄較少的表開始查詢)

3、在連線查詢的時候我們並不需要所有資料,可以把需要 排序、限制條數的表先進行排序、限定條數,再進行關聯。

4、調整使用的索引。

5、如果還是不能滿足要求需要重新 從第二步開始。

建立索引的幾大原則

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)的索引,那麼只需要修改原來的索引即可。

MySQL索引原理及慢查詢優化

通過不斷的縮小想要獲得資料的範圍來篩選出最終想要的結果,同時把隨機的事件變成順序的事件,也就是我們總是通過同一種查詢方式來鎖定資料。資料庫索引就是通過演算法提高查詢效率。磁碟io與預讀 考慮到磁碟io是非常高昂的操作,計算機作業系統做了一些優化,當一次io時,不光把當前磁碟位址的資料,而是把相鄰的資...

MySQL索引原理及慢查詢優化

2.和in可以亂序,比如a 1 and b 2 and c 3 建立 a,b,c 索引可以任意順序,mysql的查詢優化器會幫你優化成索引可以識別的形式。3.盡量選擇區分度高的列作為索引,區分度的公式是count distinct col count 表示欄位不重複的比例,比例越大我們掃瞄的記錄數越...

MySQL優化(三) 索引原理及索引優化

b tree索引,它是目前關係型資料庫中查詢資料最為常用和有效的索引,大多數儲存引擎都支援這種索引。使用b tree這個術語,是因為mysql在create table或其它語句中使用了這個關鍵字,但實際上不同的儲存引擎可能使用不同的資料結構,比如innodb就是使用的b tree。中的b是指bal...