直接起飛
1.什麼是索引?
索引是幫助mysql高效獲取資料的排好序的資料結構。
2.索引的資料結構?為什麼選這種結構?
假設我們現在這裡有一張表(以下情況都是innodb儲存引擎):
idnumber
如果mysql沒有索引這種結構,那麼我們如果查詢number為51的這行記錄,那麼mysql就要從上往下掃瞄全表,找到number為51的這行記錄需要9次;
二叉樹?
如果mysql索引結構為二叉樹呢?
我們要去查詢51這個元素:
我們只需要查詢3次就能找到51這個元素,時間複雜度為o(3);
那麼我們mysql索引用的就是二叉樹結構嗎?
肯定不是的,如果是二叉樹,那麼我把id這一列作為索引會是怎麼樣的情況:
假設我們現在要查詢id為7的這一列:
這個時候二叉樹已經是鍊錶化了,我們查詢7這個元素就需要找7次,時間複雜度為o(7);
二叉樹對於連續自增的資料會轉為鍊錶化,不適合做這種資料的查詢。我們排除這種資料結構。
紅黑樹?
假設mysql索引為紅黑樹,這個時候我們還是先去查詢number為51的這一行:
我們需要查詢4次就能找到51這個元素,時間複雜度為o(4);
再看如果查詢id為7的元素呢?
這次找id為7的元素,只找了4次,比二叉樹次數少多了;
那麼mysql用的是紅黑樹嗎?我們來思考乙個問題:
如果我資料庫裡面有幾千萬條資料,也就是說,id是自增的幾千萬個,那麼這個紅黑樹高度是不是很高,查詢元素時間複雜度為o(n);這顯然是不符合我們mysql高資料量的時候查詢;
hash表?
查詢id為7,只需要一次,很快,很棒,這也是mysql索引的一種;
但是,我們來想想這有什麼缺陷:
1.hash衝突問題;
2.如果我想查詢2
答案肯定是不行的,hash只適合做簡單查詢,但是它效率非常高,只需要去hash表中查詢一次就能精確定位到資料,但是hash表只能做一次hash運算去查詢元素,像前面的情況,就無法使用索引去查詢元素了。
來驗證一下,我們給test表加上hash索引:
查詢乙個money的區間:
直接走的全表掃瞄,並沒有走索引;
b-tree?
我們還是來查詢money為51的這行資料:
我們可以看到,一顆高度為3的b tree上,我們去查詢元素時間複雜度最多為o(3);我們去查詢51也是查詢3次,很好的解決了元素查詢問題;
再看這棵樹上面,葉子節點都是排好序的,但是需要去查詢的話,還是需要從根節點開始查詢,並沒有完美解決hash表不能做的範圍查詢;(範圍查詢時間複雜度高)
那麼mysql用的是b tree嗎?mysql用的不是b tree,我們下面來看b+tree;
b+tree
mysql索引使用的就是b+tree;為什麼mysql會選用b+tree呢?我們來看b+tree的結構:
從結構上來看,b+tree多了冗餘資料,葉子節點上面有指向下乙個葉子節點的指標;
如果是範圍查詢,我查詢到乙個資料,那麼根據葉子節點指標就能順藤摸瓜找到這個範圍能的資料,完美解決了hash表的範圍查詢;
b+tree跟b tree還有乙個區別點是b+tree(資料庫這行data)只放在了葉子節點;而b tree在第二行資料塊上面也存有著 (資料庫這行data),乙個資料庫只有16kb大小,容量有限,在有限容量下,b+tree的冗餘設計要比b tree能存放更多的資料;
3.為什麼選用innodb儲存引擎
1.表資料檔案本身就是按照b+tree組織的檔案儲存,主鍵索引上面包含了整行的全部資料,節省了磁碟空間;
2.聚集索引(主鍵索引)的葉子節點包含了整行資料;myisam引擎檔案和資料是非聚集的(索引檔案myi和資料檔案myd並不是在乙個檔案,這一點innodb都是存放在ibd檔案);
3.innodb支援事務;
4.各種索引
4.1主鍵索引(聚集索引)
以主鍵資料作為索引列,葉子節點上包含了行所有的資料:
4.2稀疏索引(輔助索引,非聚集索引)
以非主鍵列作為索引,葉子節點上面只有id,如果需要查詢這行全部資料,需要去主鍵索引上面回表:
4.3覆蓋索引
所謂覆蓋索引,其實上就是非主鍵索引,但是被稱做覆蓋索引是因為sql的查詢項中只包含了索引列和id,不需要去主鍵索引回表,這樣的操作就稱為覆蓋索引查詢。
4.4聯合索引
所謂的聯合索引,其實就是由多個字段組成的輔助索引;符合最左字首匹配規則(結合索引的有序性,就能明白為什麼是最左字首匹配原則;後面sql優化中會講到這些):
問題1:為什麼非主鍵索引葉子節點儲存的是主鍵?
可以節省磁碟儲存空間,ibd檔案會相對較小;
行資料做更改的時候並不影響輔助索引,只儲存id的奧妙所在(更改不需要去維護索引);
如果沒有主鍵就無法維護ibd檔案,innodb必須要有索引;如果建表的時候沒有設定主鍵,innodb會維護乙個隱藏列去作為主鍵索引;
自增索引插入的時候效率要比其他要高出很多;而且作為int或者long,比起uuid所占用位元組是要少的多的,也就是說,上層榮譽節點可以放更多,下層葉子節點也可以放更多的資料。
MySQL聚集索引詳解 mysql索引詳解
資料結構分,有b tree索引 b tree 雜湊索引 r tree索引等。按資料塊的順序和索引節點的邏輯順序是否一致可以分為聚集索引和非聚集索引。聚集索引由於物理塊連續,在範圍掃瞄的時候可以減少磁頭尋道時間,因而比非聚集索引高效。幾種索引型別的選擇 primary 主鍵索引。unique 唯一索引...
mysql聚集索引 MySQL索引之聚集索引介紹
在mysql裡,聚集索引和非聚集索引分別是什麼意思,有什麼區別?在mysql中,innodb引擎表是 聚集 索引組織表 clustered index organize table 而myisam引擎表則是堆組織表 heap organize table 也有人把聚集索引稱為聚簇索引。當然了,聚集索...
MySQL 聚集索引 非聚集索引簡述
mysql索引中可以分為聚集索引與非聚集索引兩類,在網路上也見過聚簇的說法,這裡先簡單介紹兩種索引的含義與適用場景。懶得畫圖,全是字。索引的鍵值邏輯順序決定了表資料行的物理儲存順序,也就是在資料庫上連線的記錄在磁碟上的物理儲存位址也是相鄰的,注意這一點特性,我們可以分析出它的適用情況。由於聚集索引規...