索引是為了加速對錶中資料行的檢索而建立的一種分散儲存的資料結構
索引能極大的減少儲存引擎需要掃瞄的資料量
索引可以把隨機io變為順序io
索引可以幫助我們在進行分組、排序等操作時,避免使用臨時表
為了說明索引的資料結構,先對比一下幾種常見的資料結構特點
在二叉樹中,左子樹的鍵值總是小於根的鍵值,右子樹的鍵值總是大於根的鍵值
當插入資料都大於節點時會形成線性鍊錶結構。所以二叉樹查詢效率取決於資料的分布
首先符合二叉查詢樹的定義,其次必須滿足任何節點的兩個子樹的高度最大差為1
為了達到平衡需要經過1次或多次的左旋和右旋操作,雖然查詢速度比普通二叉樹快了,但是維護成本增加
缺點:深度太大:資料所處的深度決定了它的io操作次數,io操作耗時大
容量太小:每乙個磁碟塊(節點、頁)儲存的資料量太小了
沒有很好的利用操作磁碟io的資料交換特性
也沒有利用好磁碟io的預讀能力(空間區域性性原理),從而帶來頻繁的io操作
特點:
不再是二叉搜尋,而是m叉搜尋
葉子節點,非葉子節點都儲存資料;
中序遍歷,可以獲得所有節點
b+tree是在btree的基礎上進化而來
b+tree和btee的區別:
b+tree節點關鍵字搜素採用閉合區間(左閉合,插入都是往右邊插入,提高了效率,保證了順序)
由這個特點可得出:定義資料型別時盡量短,有利於索引的建立,可容納更多的資料; 選擇索引關鍵字時盡量選擇小的字段,增加索引的容量; 索引過多會影響update,insert操作效率,因為要保證索引樹的絕對平衡需要移動很多索引節點
3.b+tree關鍵字對應的資料儲存在葉子節點中
4.b+tree葉子節點是順序排列的,並且相鄰節點具有順序引用的關係,增加了鍊錶結構,(獲取所有節點不再需要中序遍歷,本身就是有序排列的,且相鄰節點也是通過鍊錶有序連線的;範圍查詢優化)
相對於btree,b+tree優點:
b+tree擁有btree的所有優點
b+tree掃庫、掃表能力更強
b+tree磁碟讀寫能力更強
b+tree排序能力更強
b+tree查詢效率更加穩定
根據上述各種資料結構的比較,顯然b+tree最適合作為索引的資料結構,mysql中索引就是用的b+tree結構
myisam儲存引擎資料分兩個檔案儲存myd(資料檔案)和myi(索引檔案),還有預設的frm(表結構描述檔案,mysql8取消了frm檔案)
主鍵索引葉子節點不儲存資料,只儲存資料位址,指向myd檔案
輔助索引結構和主鍵索引一樣
以主鍵為索引(聚集索引)來組織資料的儲存
資料和索引都儲存在同乙個檔案中(ibd字尾檔案)
假如表沒有顯示的指定主鍵索引,innodb會隱式的建立乙個6byte int型別的主鍵索引
資料發生遷移時,輔助索引可不變
聚集索引:資料庫表中資料的物理順序與鍵值的邏輯順序(索引)相同,順序io查詢
由上面的索引結構可以推斷出索引的優化原理
離散性越高,選擇性越好(離散性低的資料重複多,選擇就多,不利於檢索資料。盡量選擇離散性高的列來建立索引)
對索引中關鍵字進行計算(對比),一定是從左往右依次進行,且不可跳過
聯合索引列選擇原則:
經常使用的列優先【最左匹配原則】
選擇性高(離散性高)的列優先【離散性原則】
寬度小的列優先【最少空間原則】(寬度小,非葉子節點上能儲存的關鍵字就多)
例:假如存在聯合索引name,phonenum
則 select * from where name = ? 會命中該聯合索引【最左匹配原則】,跟 like "***%"能使用索引原理一樣
聯合索引中存在某個列就不需要再對此列建索引
如果查詢列可通過索引節點中的關鍵字直接返回,則該索引稱之為覆蓋索引。(select * 沒有機會命中覆蓋索引)
覆蓋索引可以減少資料庫io,將隨機io變為順序io,可提高查詢效能
索引字段最好不要允許為空,null在mysql中需要特殊處理增加運算和空間
唯一索引允許多個資料為null
乙個查詢只會走乙個索引
索引列的資料長度能少則少(所以在定義表結構時盡量定的資料型別長度合理,且不要在長字段上建立索引)
索引要建立合適,過多索引反而會影響效率,且遷移麻煩,儲存增大,刪除、修改、新增時非常影響效率,因為資料改變索引也會跟著改變,索引維護耗費效能
匹配列字首可用到索引 like ***%, like %***%、 like %***用不到索引;
where條件中 not in 和<>操作無法使用索引(大概率情況下,具體要看執行成本,詳見:mysql優化系列2.1-mysql中 is null、is not null、!= 能用上索引嗎?);
多用指定列查詢,只返回需要的資料列,盡量避免 select * (指定查詢欄位有可能命中覆蓋索引)
聯合索引中如果不是按照索引最左列開始查詢,無法使用索引
聯合索引中精確匹配最左前列並範圍匹配另外一列可以用到索引;
聯合索引中如果查詢中有某個列的範圍查詢,則其右邊的所有列都無法使用索引;
視覺化演算法演示:
索引原理和優化
mysql的基本儲存結構是頁 記錄都存在頁裡邊 各個資料頁可以組成乙個雙向鍊錶 每個資料頁中的記錄又可以組成乙個單向鍊錶 使用索引後 沒有用索引我們是需要遍歷雙向鍊錶來定位對應的頁,現在通過 目錄 就可以很快地定位到對應的頁上了!二分查詢,時間複雜度近似為 o logn 其實底層結構就是 b 樹,b...
MySQL優化(三) 索引原理及索引優化
b tree索引,它是目前關係型資料庫中查詢資料最為常用和有效的索引,大多數儲存引擎都支援這種索引。使用b tree這個術語,是因為mysql在create table或其它語句中使用了這個關鍵字,但實際上不同的儲存引擎可能使用不同的資料結構,比如innodb就是使用的b tree。中的b是指bal...
MYSQL索引原理,優化SQL
索引型別 b tree mongodb b bree mysql hash mysql引擎 innodb myisame memory b tree 多路平衡搜尋數,degree代表最多分的叉。為了減少樹的高度,從而減少 io次數。一頁 預設 16 kb 的話 每一頁 包含資料 b tree 公升級...