MySQL技術內幕 五 索引與演算法

2021-08-21 04:25:00 字數 3210 閱讀 7626

一:索引概述:innodb支援兩種常見索引,一種是b+樹索引一種是雜湊索引。雜湊索引是自適應的,引1擎會根據表的使用情況自動為表生成雜湊索引,不能人為干預是否在一張表裡生成雜湊索引

b+樹索引就是傳統意義上的索引,這是關係型資料庫中最常用、有效的索引、b+樹索引的構造類似於二叉樹,根據鍵值快速找到資料。 記住:b不是二叉(binary),而是代表平衡(balance),從最早的平衡二叉樹演化來的。但不是乙個二叉樹。

二:二叉查詢樹

二叉查詢樹特性:只要滿足了左節點的資料比根節點小,右節點的資料比根節點大的樹形結構即可,不一定非要左右對稱。但是這種情況會導致

當出現該情況後,二叉查詢樹的效能就比較低效,沒能發揮二叉樹的2n次冪查詢的優勢,因此需要改進,因此引出了新的定義----平衡二叉樹

三:平衡二叉樹:符合二叉查詢樹的定義,其次滿足任何節點的左右兩個子樹的高度最大差為1

。(應該是左節點(或者是有兩個子節點的左節點)與右節點(有兩個子節點的最底層節點)的差距)。當插入或者刪除、更新時,要保證其平衡二叉樹的性質,需要通過多次左旋或者右旋來保證平衡

此時需要一定的開銷來維護

四:b+樹

b+樹是為磁碟或者其他直接訪問輔助裝置而設計的一種平衡查詢樹。在b+樹中,所有記錄節點都是按照鍵值的大小順序存放在同一層的葉節點中,各葉節點指標進行連線。下面的b+樹,高度為2,每頁存放4條記錄,扇出為5

五:b+樹索引

b+樹索引本質就是b+樹在資料庫中的實現,但是b+索引在資料庫中有乙個特點:高扇出性(也就是乙個索引裡面儲存了大範圍資料),因此其高度一般在2-3層,最多隻需要2-3次io,一秒100次一般,所以只需0.03s左右

b+樹索引分為  聚集索引(clustered index)和輔助聚集索引(secondary index).無論哪個,內部都是b+樹的,高度平衡。葉節點存放著所有的資料。

1>聚集索引:聚集索引就是按照每張表的主鍵構造一顆b+樹,並且葉節點中存放著整張表的行記錄資料,因此也讓聚集索引的葉節點成為資料頁,這個特性決定了索引組織表中資料也是索引的一部分。同b+樹資料結構一樣,每個資料頁都通過乙個雙向鍊錶來進行鏈結。

重點來了:由於實際資料頁只能按照一顆b+樹進行排序(不可能為了不同索引建立不同個資料格式也就是不同個表),因此每張表只能擁有乙個聚集索引。許多情況下,查詢優化器非常傾向於採用聚集索引,因為能夠在索引的葉節點上直接找到資料。此外,由於定義了資料的邏輯順序,聚集索引能夠特別快地訪問針對範圍值的查詢。查詢優化器能夠快速發現某一段範圍的資料頁需要掃瞄。許多文件說:聚集索引按照順序物理的儲存資料,這樣維護成本非常高。所以它的儲存並不是物理上的連續,是邏輯上的連續。一是我們前面說過的頁通過雙向鍊錶鏈結,頁按照主鍵的順序排列。另乙個是每個頁中的記錄也是通過雙向鍊錶進行維護,物理儲存上可以同樣不按照主鍵儲存。

2>非聚集索引(輔助索引):葉級別不包含行的全部資料。葉節點除了包含鍵值以外,每個葉級別中的索引行中還包含了乙個書籤,該書籤用來告訴儲存引擎,**可以找到與索引相對應的行資料。因為是索引組織表,因此書籤就是相應行資料的聚集索引鍵(本質上還是通過這個索引去找到對應的聚集索引所在的地方,間接查詢出來)

說明:當通過輔助索引來尋找資料時,引擎會遍歷輔助索引並通過葉級別的指標獲得指向主鍵索引的主鍵,在通過主鍵索引來找到乙個完整的行記錄。

3>新建索引問題:對於索引的新增或者刪除操作,資料庫先建立一張新的臨時表,然後把資料倒入臨時表,刪除原表,再把臨時表重新命名為原來的表名。對於一張大表,新增和刪除索引需要很長的時間。從innodb plugin開始,支援快速索引建立方法。只限定與輔助索引,對於主鍵的操作還是需要重建一張表,操作時會對錶加上乙個s鎖,因此建立的過程中該表只能進行讀操作。 六:

b+樹索引的使用

訪問表中很少一部分行時,使用b+樹索引才有意義。對於性別字段、地區字段、型別字段,可取值範圍很小,低選擇性。假如對性別進行索引,如:select * from student where *** = 「m」,此時可能結果是50%的資料。這時新增索引完全沒有必要。如果某個字段取值範圍很廣,幾乎沒有重複,高選擇性,最合適。

但是!!!!!!:如果從表中取出很少一部分行時,對這個字段新增b+樹索引是非常必要的,但是如果出現了訪問欄位是高選擇性,但是取出的行資料佔表中大部分的資料時,只是資料庫不會使用b+樹索引。(優化器沒有使用索引),mysql資料庫的優化器會通過explain的rows欄位預估查詢可能得到的行,如果大於某乙個值,則b+樹會選擇全表的掃表,至於這個值,可能在20%左右,即超過20%,優化器不會使用索引,而進行全表掃瞄,但是優化器選擇的該策略不一定最優,因為預估的返回行和實際返回行可能差距比較大,因此需要根據實際情況是否強制使用索引。

七:順序讀、隨機讀與預讀取

為什麼索引使用原則為 高選擇、取出表中少部分資料。但是為什麼少部分?

概念:順序讀:是指順序地讀取磁碟上的塊(block),隨機讀 是指訪問的塊不是連續的,需要磁碟的磁頭不斷移動。當前傳統磁碟的瓶頸之一就是隨機讀取的速度較低。在資料庫中,順序讀是指根據索引的葉節點資料就能順序地讀取所需的行資料,這個順序只是邏輯地順序讀,在物理磁碟上還是隨機讀取。但相對來說,物理磁碟上的資料還是比較順序的。因為是根據區來管理,區是64個連續頁,如根據主鍵進行讀取,或許通過輔助索引的葉節點就能讀取到資料。

隨機讀:一般是訪問輔助葉節點不能完全得到結果的。需要根據輔助索引葉節點中的主鍵去找實際行資料。一般來說,輔助索引和主鍵所在的資料段不同,因此訪問是隨機的方式。正因為讀取的方式是隨機的,並且隨機讀的效能遠低於順序讀,因此優化器才會選擇全表的掃瞄方式,而不是去走輔助索引。

總結:之所以會因為資料量大而不走索引,是因為資料區是由區來管理,裡面有64個連續頁,當資料量少的時候,都在同乙個區或者其他區(索引組織表會使得索引是採用陣列方式順序排列,區挨得近),此時就是順序讀,走索引,而當資料量過大時,此時已經產生許多區(或者導致不在同乙個段裡面),一般來說輔助索引和主鍵所在的資料段不同,因此就會隨機讀取,此時優化器經過分析覺得隨機讀效能太低,因此不走設定的索引,而採用全表讀取

為了提高讀取效能,innodb儲存引擎引入了預讀取技術,是指通過一次 io 請求將多個頁預讀取到緩衝池中,並且估計預讀取的多個頁馬上會被訪問。傳統的io每次只讀取1頁。(192頁)

MySQL技術內幕 16 索引組織表

在 innodb儲存引擎中,表都是根據主鍵順序組織存放的,這種儲存方式的表稱為索引組織表 index orgnaized table 在 innodb儲存引擎表中,每張表都有個主鍵 primary key 如果在建立表時沒有顯式地定義主鍵,則 innodb儲存引擎會按如下方式選擇或建立主鍵 當表中有...

ObjectBuilder技術內幕 五

從前面的論述中,我們看到乙個物件的建立過程十分複雜和繁瑣,遠不是乙個 new那麼簡單,涉及到許多物件,建立器上下文 策略 方針等等等等。但由於採用了良好的設計模式,是這些眾多的物件協同工作次序井然。建立器採用建立者設計模式,把一系列物件的建立工作加以封裝,使呼叫者只要對其進行配置,然後呼叫 buil...

MySQL技術內幕

innodb儲存引擎是事物安全的儲存引擎。innodb儲存引擎有多個記憶體塊,這些記憶體塊組成乙個很大的記憶體池,負責如下的工作 後台執行緒 innodb儲存引擎是多執行緒模型,因此他有多個不同的後台執行緒,負責處理不同的任務。記憶體日誌檔案 記錄mysql對某種條件做出響應時的檔案,如錯誤日誌檔案...