索引底層數據結構與算法
索引
- 索引是幫助MySQL高效獲取數據的排好序的數據結構
- 索引存儲在文件裏
- 索引結構
- 二叉樹
- 紅黑樹
- HASH
- Btree
索引結構爲什麼選擇Btree或者B+ tree
- 二叉樹:平衡二叉樹遇到有序的數據會退化成鏈表,查詢效率降低
- 紅黑樹:自平衡的二叉樹,雖然可以自平衡,但是在數據量較大的情況下,樹的高度也會變得很大,對海量數據來說依然不是最合理的數據結構。
- Hash:
- hash表只能匹配是否相等,不能實現範圍查找。
- 當需要按照索引進行order by時,hash值沒辦法支持排序
- 當數據量很大時,hash衝突的概率也會非常大
- 組合索引可以支持部分索引查詢,如(a,b,c)的組合索引,查詢中只用到了a和b也可以查詢的,如果使用hash表,組合索引會將幾個字段合併hash,沒辦法支持部分索引
磁盤存取原理
知識擴展
打開一個word文檔會經歷哪些過程
- 鼠標雙擊word文檔,這樣就輸入了一條指令——打開這個word文檔,word文檔是存儲在硬盤上的,由於CPU並不能直接調用存儲在硬盤上的數據
- CPU收到這條指令後,會將這個word文檔從硬盤讀取出來,存放到RAM(內存中,所有數據都是二進制碼)中
- CPU再從內存中讀取二進制碼,“翻譯二進制碼”
- CPU翻譯結果傳輸到輸出設備(即顯示器),這時候你就能在顯示器上看到這個word文檔的內容了。
Java程序操作(增刪改查)數據庫數據的簡易圖
磁盤存取原理
- 尋道時間(速度慢,費時)
- 旋轉時間(速度較快)
主要爲了減少尋道時間
B樹
描述
- 度(Degree)-節點的數據存儲個數
- 葉節點具有相同的深度
- 葉節點的指針爲空
- 節點中的數據key從左到右遞增排列
特點
繼承了平衡二叉樹的所有特點,並將其發展成多叉樹,每個節點可以存儲更多的數據(度)
B+ 樹
描述
- 非葉子節點不存儲data,只存儲key,可以增大度
- 葉子節點存儲指針
- 順序訪問指針,提高區間訪問的性能
特點
繼承了B樹的特點,並在其基礎上進一步優化,非葉子節點只存儲key,葉子節點存儲所有的數據,並使用指針相連。
兩種搜索引擎在索引上的對比
- InnoDB是聚集索引,使用B+Tree作爲索引結構,數據文件是和(主鍵)索引綁在一起的(表數據文件本身就是按B+Tree組織的一個索引結構),必須要有主鍵,通過主鍵索引效率很高。但是輔助索引需要兩次查詢,先查詢到主鍵,然後再通過主鍵查詢到數據。因此,主鍵不應該過大,因爲主鍵太大,其他索引也都會很大。MyISAM是非聚集索引,也是使用B+Tree作爲索引結構,索引和數據文件是分離的,索引保存的是數據文件的指針。主鍵索引和輔助索引是獨立的。
- InnoDB的B+樹主鍵索引的葉子節點就是數據文件,輔助索引的葉子節點是主鍵的值;MyISAM的B+樹主鍵索引和輔助索引的葉子節點都是數據文件的地址指針。
B+樹索引性能分析
- 一般使用磁盤I/O次數評價索引結構的優劣
- 預讀:磁盤一般會順序向後讀取一定長度的數據(頁的整數倍)放入內存
- 局部性原理:當一個數據被用到時,其附近的數據也通常會馬上被使用
- B+Tree節點的大小設爲等於一個頁,每次新建節點直接申請一個頁的空間,這樣就保證一個節點物理上也存儲在一個頁裏,就實現了一個節點的載入只需一次I/O
- B+Tree的度d一般會超過100,因此h非常小(一般爲3到5之間)
MyISAM索引實現(非聚集)
MyISAM索引文件和數據文件是分離的
主鍵索引
其它索引
InnoDB索引實現(聚集)
- 數據文件本身就是索引文件
- 表數據文件本身就是按B+Tree組織的一個索引結構文件
- 聚集索引-葉節點包含了完整的數據記錄
- InnoDB表必須有主鍵,並且推薦使用整型的自增主鍵
InnoDB爲什麼推薦使用自增ID作爲主鍵?
答:自增ID可以保證每次插入時B+索引是從右邊擴展的,可以避免B+樹和頻繁合併和分裂(對比使用UUID)。如果使用字符串主鍵和隨機主鍵,會使得數據隨機插入,效率比較差。 - 非主鍵索引結構葉子節點存儲的是主鍵值(一致性和節省存儲空間)
主鍵索引
其它索引
索引最左前綴原理
在mysql建立聯合索引時會遵循最左前綴匹配的原則,即最左優先,在檢索數據時從聯合索引的最左邊開始匹配