文章是學習了林曉斌老師在極客時間的《mysql實戰45講》後,根據本身的理解整理而成的。mysql
當咱們使用漢語字典查找某個字時,咱們會先經過拼音目錄查到那個字所在的頁碼,而後直接翻到字典的那一頁,找到咱們要查的字,經過拼音目錄查找比咱們拿起字典從頭一頁一頁翻找要快的多,數據庫索引也同樣,索引就像書的目錄,經過索引能極大提升數據查詢的效率。sql
在數據庫中,常見的索引實現方式有哈希表、有序數組、搜索樹數據庫
二叉搜索樹:一棵空樹,或者是具備下列性質的二叉樹: 若它的左子樹不空,則左子樹上全部結點的值均小於它的根結點的值; 若它的右子樹不空,則右子樹上全部結點的值均大於它的根結點的值; 二叉搜索樹的左、右子樹也分別爲二叉搜索樹。
平衡二叉樹:平衡二叉樹是在二叉搜索樹的基礎上引入的,指的是結點的左子樹和右子樹的深度差不超過1.
多叉樹:每一個結點能夠有多個子結點,子節點的大小從左到右依次遞增。數組
當使用平衡二叉實現索引時,結構以下圖
從圖中可發現,每次查詢最多須要訪問4個節點必能獲得所要數據。例如查詢user2時,查詢過程爲:userA-->userC-->userF-->user2。
因此查詢速度很高,同時,由於搜索樹的特性(左子樹小於右子樹),區間查詢也很方便。
<br>
若是搜索樹存於內存中,與多叉樹相比,二叉樹的搜索速率是最高的,但實際上數據庫使用的是n叉樹而不是二叉樹。ide
一、索引不只存於內存,仍是寫到磁盤上
二、搜索樹上的每一個結點在磁盤上表現爲一個數據塊
三、多叉樹每一個結點下能夠有多個子節點,因此存儲相同數據量時多叉樹的樹高比二叉樹小,查詢一個數據須要訪問的結點數更少,即查詢過程訪問更少的數據塊。查詢速度較高。函數
innodb使用B+樹做爲索引結構。
在B+樹中,咱們將節點分爲葉子結點和非葉子結點,非葉子結點上保存的是索引,並且一個節點能夠保存多個索引;數據所有存於葉子結點上,根據葉子結點的內容不一樣,innodb索引分爲主鍵索引和非主鍵索引。非主鍵索引也稱爲二級索引。
主鍵索引的葉子結點中保存的數據爲整行數據,而非主鍵索引葉子節點保存的是主鍵的值。
主鍵索引圖
非主鍵索引圖
經過主鍵索引查詢數據時,咱們只需查找主鍵索引樹即可以獲取數據;經過非主鍵索引查詢數據時,咱們先經過非主鍵索引樹查找到主鍵值,而後再在主鍵索引樹搜索一次,這個過程稱爲回表,也就是說非主鍵索引查詢會比主鍵查詢多搜索一棵樹。因此咱們應儘量使用主鍵查詢。性能
添加新行時,將會在索引表上添加一條記錄,若是是索引遞增插入時,數據都是追加在當前最大索引以後,不會對樹中其餘數據形成影響;若是新加入的數據的索引值位於節點的中間,須要挪動部分節點的位置,從而保持索引樹的有序性。
並且,相鄰多個節點是存儲在同一個數據頁上的,此時,若是是在已經存儲滿狀態的數據頁中插入節點,會申請新的數據頁,將部分數據挪動到新的數據頁,這個過程稱爲頁分裂,頁分裂除了會影響性能,還會下降磁盤空間利用率。不規則數據插入時,會形成頻繁的頁分裂。學習
當相鄰兩個頁因爲刪除了數據,利用率很低以後,會將數據頁作合併orm
因此,通常狀況下會採用遞增主鍵,使新數據遞增插入。blog
使用業務邏輯字段作主鍵有什麼優缺點?
一、業務邏輯字段不容易保證索引樹結點有序插入,這樣寫入成本較高。
二、innodb默認使用整數類型做爲主鍵,主鍵長度較小,二級索引的葉子結點中保存的是主鍵值,主鍵長度越小,二級索引的葉子結點佔用空間也就越小。
三、固然,使用業務邏輯字段作主鍵也有好處,能夠避免回表,每次只需掃描一次主鍵索引樹便可
綜上,從性能和存儲空間方面考量,自增主鍵每每是更合理的選擇,當業務場景有且只有一個索引,並且該索引爲惟一索引時,此時更適合使用業務邏輯字段做爲主鍵。
由於數據修改/刪除、頁分裂等緣由,會致使數據頁空間利用率下降,此時,能夠考慮重建索引,將數據按順序插入,提升磁盤空間利用率。但重建主鍵索引和普通索引會有不一樣影響,重建普通索引,能夠達到提升空間利用率的目的,且不會對其餘索引形成影響,但若是重建主鍵索引就不合理了,會影響全部普通索引,性能影響較大,並且不管是新建/刪除主鍵,都會重建整張表。這時咱們可使用alter table T engine=InnoDB這個語句代替。
查看索引利用率
查看performance_schema.table_io_waits_summary_by_index_usage表