# index 索引 ###### tags: `mysql` ## index 原理 - index分類 - 二元樹 - hash index ## hash index 時間複雜度: O(1) 最常見的 innodb 不支援 hash index, 主要原因: - hash index 適合`精確`查詢, 範圍查詢就不適合 > [mysql hash index & adaptive hash index](https://www.modb.pro/db/113573) ## 二元樹 (binary tree) - 時間複雜度 O(n) - 一個節點只能有兩個子節點 - 左邊節點小於本節點, 右邊節點大於本節點 ### 平衡二元樹 - 根節點會隨著數據改變 - 數據越多, 遍歷次數越多, IO時間越長 ## B tree (二三樹) point: 儲存child的 address data: save value 當數據大時,會導致Btree很深,增加IO的讀取次數,影響查詢效率 ## B+ Tree 我們也可說他是一顆二元樹,MYSQL index最小單位為 `page` 當要查詢一筆數據時,會先從root page 開始尋找,page 內放 兩個 index key 例如設定id 根據id值往下搜尋page內的數據 - 每一個節點都帶有下一個節點的point - 所有查詢最後都會到 page 去查詢結果 ## 稀疏索引 & 密集索引 Dense: 密集 Sparse: 稀疏 ## 二級索引 Secondary Indexes: 二級索引 ## Binary Tree 與 B+Tree差異 - B+樹從下而上插入 - --- ## mysql data page 為最小單位 - file.frm: 表結構 - file.ibd: index and data ## 回表查詢 使用聚集索引可以直接查詢到指針內的數據, 如果是普通索引就需要掃描兩遍 index tree, 先透過 index 找到 PK, 再透過 cluster index 定位數據, 這就是 `回表查詢` ### why不能建太多index 建立一個index時,都是去實作一顆btree,這也是為什麼 不能建立太多index, index也會占用空間 --- ## 索引使用場景 ### 適合使用索引 - 頻繁作為查詢條件的字段應該創建索引 - 多表查詢中與其它表進行關聯的字段,外鍵關係建立索引 - 單列索引/複合索引的選擇,高併發下傾向於創建複合索引 - 查詢中經常用來排序的字段 - 查詢中經常用來統計或者分組字段 ### 不適合使用索引 - 頻繁更新的字段: 每次更新都會影響索引樹 - where條件查詢中用不到的字段 - 表記錄太少 - 經常增刪改的表: 更新了表,索引也得更新才行 - 注意: 如果一張表中,重複的記錄非常多,為它建立索引就沒有太大意義 ## 參考資料 > [MYSQL 索引參考](https://juejin.cn/post/6931901822231642125) >