一句話總結:索引是幫助mysql快速高效獲取資料的 排好序 的 資料結構;
如果我們資料庫建表時不建索引直接查詢,資料庫只能遍歷比較,時間複雜度為:o(n);
比如我們查詢索引為10的資料,遵從樹結構左小右大的原則,三次就可以查詢出想要的索引,根據索引獲取資料磁碟位址,時間複雜度為:o(log n);但是二叉樹有乙個問題,如果從根節點是到葉子節點是順序插入的話,二叉樹就會變成乙個線性的鍊錶,這個時候和直接遍歷資料沒有區別,時間複雜度:o(n);
這個時候我們思考一下,如果有一種平衡樹,就可以提高效率,降低時間損耗,也就是下面的平衡二叉樹(紅黑樹);
這個時候,時間複雜度就會一直為:o(log n);但是我們還可以再思考一下,紅黑樹有沒有問題呢?肯定是有的,隨著資料量的變大,樹的高度會越來越高,我們查詢的元素就越來越多,所以紅黑樹也是不行的;
我們繼續思考,如果可以控制高度,是不是就解決了這個問題?
如果可以控制高度,將父節點的資料橫向擴充套件,效能將會得到進一步的提公升,這個時候b-tree就登場了,其實我們的資料庫索引就是基於b-tree實現的;
b-tree可以對樹的每個節點做橫向的擴充套件,既解決了鍊錶問題,也保證樹的高度不要太高,也就是每乙個節點都存放索引和data,這種橫向擴充套件的結構我們稱做為頁;既然b-tree這麼完美,那為什麼mysql沒有選擇用b樹做索引結構呢?因為每個頁裡面都存放資料,帶來了極大的io開銷,資料量如果很大,載入時記憶體損耗嚴重;
有什麼辦法可以解決嗎?
如果我們只把資料存放在葉子節點上,父節點不存放資料,載入時根據父節點只載入某個葉子節點的資料,是不是就可以節省很多記憶體;b+tree完全滿足我們的想法;
b+tree相較於b樹有兩個改變:
將資料只存在在葉子節點上(冗餘),非葉子節點不儲存data,這樣可以存放更多的索引;
葉子節點包含所有的索引;
葉子節點用指標連線,提高區間訪問的效能;
資料存在葉子節點的好處?
根節點和中間節點就能儲存更多的索引資料;
葉子節點的橫向指標的好處?
葉子節點的橫向指標可以支援範圍查詢,比如我們要查詢上圖中索引大於4的資料,只需要獲取指標右邊的所有資料就行,非常方便;
將索引通過雜湊演算法以後儲存,精確查詢可以快速定位到資料位址;
但是有乙個很嚴重的問題,不支援範圍查詢,因為hash運算以後的資料是沒有順序的,也不存在指標,所以無法進行範圍查詢;
葉子節點的data存放了實際資料的就是聚簇索引,反之是非聚簇索引;
聚簇索引:innerdb就是聚簇索引的實現,葉子節點的data存放了實際資料;
整形比較索引時方便;
整形占用空間小;
自增是為了防止**,減少樹的自旋,降低效能開銷;
建議使用innerdb引擎,支援事務、表鎖、行鎖、聚簇索引;
最好有整形自增主鍵,強調一點根據資料量選用int或者bigint,盡量避免主鍵到頭的尷尬;
索引最好有唯一索引和復合索引搭配使用,不要濫建索引,會降低寫的效能,樹的旋轉耗時;
列欄位占用空間越小越好,可以使用列舉來代替字串;
最好有create_time 和 update_time欄位,方便定位問題;
最好預留幾個字段,方便擴充套件;
字段備註越詳細越好,方便後來者熟悉業務;
資料表最好一次建好,後續執行dml會耗時,表越大越耗時,修改過程中會拒絕寫操作;
表字段不宜太多,可以垂直拆分成多個表;
MySQL索引原理之索引原理
索引定義 是儲存引擎用於快速查詢記錄的一種資料結構。需要額外開闢空間和資料維護工作。索引是物理資料頁儲存,在資料檔案中 innodb,ibd檔案 利用資料頁 page 儲存。索引可以加快檢索速度,但是同時也會降低增刪改操作速度,索引維護需要代價。索引涉及的理論知識 二分查詢法 hash和b tree...
mysql索引 mysql索引實現原理
什麼是索引 索引是一種高效獲取資料的儲存結構,例 hash 二叉 紅黑。mysql為什麼不用上面三種資料結構而採用b tree 若僅僅是 select from table where id 45 上面三種演算法可以輕易實現,但若是select from table where id 6 就不好使了...
mysql 索引原理
b樹 b樹高度 資料庫為什麼使用這種結構?一般來說,索引本身也很大,不可能全部儲存在記憶體中,因此索引往往以索引檔案的形式儲存的磁碟上。這樣的話,索引查詢過程中就要產生磁碟i o消耗,相對於記憶體訪問,i o訪問的消耗要高幾個數量級,所以評價乙個資料結構作為索引的優劣最重要的指標就是在查詢過程中磁碟...