b樹
b樹高度
資料庫為什麼使用這種結構?
一般來說,索引本身也很大,不可能全部儲存在記憶體中,因此索引往往以索引檔案的形式儲存的磁碟上。這樣的話,索引查詢過程中就要產生磁碟i/o消耗,相對於記憶體訪問,i/o訪問的消耗要高幾個數量級,所以評價乙個資料結構作為索引的優劣最重要的指標就是在查詢過程中磁碟i/o操作次數的漸進複雜度。換句話說,索引的結構組織要儘量減少查詢過程中磁碟i/o的訪問次數。
為了達到這個目的,磁碟按需讀取,要求每次都會預讀的長度一般為頁的整數倍。而且資料庫系統將乙個節點的大小設為等於乙個頁,這樣每個節點只需要一次i/o就可以完全載入。每次新建節點時,直接申請乙個頁的空間,這樣就保證乙個節點物理上也儲存在乙個頁裡,加之計算機儲存分配都是按頁對齊的,就實現了乙個node只需一次i/o。並把b-tree中的m值設的非常大,就會讓樹的高度降低,有利於一次完全載入
mysql的索引包括普通索引、唯一性索引、全文索引、單列索引、多列索引和空間索引等。本小節將詳細講解這幾種索引的含義和特點。
1.普通索引
在建立普通索引時,不附加任何限制條件。這類索引可以建立在任何資料型別中,其值是否唯一和非空由字段本身的完整性約束條件決定。建立索引以後,查詢時可以通過索引進行查詢。例如,在student表的stu_id欄位上建立乙個普通索引。查詢記錄時,就可以根據該索引進行查詢。
2.唯一性索引
使用unique引數可以設定索引為唯一性索引。在建立唯一性索引時,限制該索引的值必須是唯一的。例如,在student表的stu_name欄位中建立唯一性索引,那麼stu_name欄位的值就必需是唯一的。通過唯一性索引,可以更快速地確定某條記錄。主鍵就是一種特殊唯一性索引。
3.全文索引
使用fulltext引數可以設定索引為全文索引。全文索引只能建立在char、varchar或text型別的字段上。查詢資料量較大的字串型別的字段時,使用全文索引可以提高查詢速度。例如,student表的information欄位是text型別,該欄位包含了很多的文字資訊。在information欄位上建立全文索引後,可以提高查詢information欄位的速度。mysql資料庫從3.23.23版開始支援全文索引,但只有myisam儲存引擎支援全文檢索。在預設情況下,全文索引的搜尋執行方式不區分大小寫。但索引的列使用二進位制排序後,可以執行區分大小寫的全文索引。
4.單列索引
在表中的單個欄位上建立索引。單列索引只根據該欄位進行索引。單列索引可以是普通索引,也可以是唯一性索引,還可以是全文索引。只要保證該索引只對應乙個字段 即可。
5.多列索引
多列索引是在表的多個欄位上建立乙個索引。該索引指向建立時對應的多個字段,可以通過這幾個字段進行查詢。但是,只有查詢條件中使用了這些欄位中第乙個欄位時,索引才會被使用。例如,在表中的id、name和***欄位上建立乙個多列索引,那麼,只有查詢條件使用了id欄位時該索引才會被使用。
6.空間索引
使用spatial引數可以設定索引為空間索引。空間索引只能建立在空間資料型別上,這樣可以提高系統獲取空間資料的效率。mysql中的空間資料型別包括geometry和point、linestring和polygon等。目前只有myisam儲存引擎支援空間檢索,而且索引的字段不能為空值。對於初學者來說,這類索引很少會用到。
如上圖,是一顆b+樹,這裡只說一些重點,淺藍色的塊我們稱之為乙個磁碟塊,可以看到每個磁碟塊包含幾個資料項(深藍色所示)和指標(黃色所示),如磁碟塊1包含資料項17和35,包含指標p1、p2、p3,p1表示小於17的磁碟塊,p2表示在17和35之間的磁碟塊,p3表示大於35的磁碟塊。真實的資料存在於葉子節點即3、5、9、10、13、15、28、29、36、60、75、79、90、99。非葉子節點只不儲存真實的資料,只儲存指引搜尋方向的資料項,如17、35並不真實存在於資料表中。
b+樹的查詢過程
如圖所示,如果要查詢資料項29,那麼首先會把磁碟塊1由磁碟載入到記憶體,此時發生一次io,在記憶體中用二分查詢確定29在17和35之間,鎖定磁碟塊1的p2指標,記憶體時間因為非常短(相比磁碟的io)可以忽略不計,通過磁碟塊1的p2指標的磁碟位址把磁碟塊3由磁碟載入到記憶體,發生第二次io,29在26和30之間,鎖定磁碟塊3的p2指標,通過指標載入磁碟塊8到記憶體,發生第三次io,同時記憶體中做二分查詢找到29,結束查詢,總計三次io。真實的情況是,3層的b+樹可以表示上百萬的資料,如果上百萬的資料查詢只需要三次io,效能提高將是巨大的,如果沒有索引,每個資料項都要發生一次io,那麼總共需要百萬次的io,顯然成本非常非常高。
b+樹性質
1.通過上面的分析,我們知道io次數取決於b+數的高度h,假設當前資料表的資料為n,每個磁碟塊的資料項的數量是m,則有h=㏒(m+1)n,當資料量n一定的情況下,m越大,h越小;而m = 磁碟塊的大小 / 資料項的大小,磁碟塊的大小也就是乙個資料頁的大小,是固定的,如果資料項佔的空間越小,資料項的數量越多,樹的高度越低。這就是為什麼每個資料項,即索引欄位要盡量的小,比如int佔4位元組,要比bigint8位元組少一半。這也是為什麼b+樹要求把真實的資料放到葉子節點而不是內層節點,一旦放到內層節點,磁碟塊的資料項會大幅度下降,導致樹增高。當資料項等於1時將會退化成線性表。
2.當b+樹的資料項是復合的資料結構,比如(name,age,***)的時候,b+數是按照從左到右的順序來建立搜尋樹的,比如當(張三,20,f)這樣的資料來檢索的時候,b+樹會優先比較name來確定下一步的所搜方向,如果name相同再依次比較age和***,最後得到檢索的資料;但當(20,f)這樣的沒有name的資料來的時候,b+樹就不知道下一步該查哪個節點,因為建立搜尋樹的時候name就是第乙個比較因子,必須要先根據name來搜尋才能知道下一步去**查詢。比如當(張三,f)這樣的資料來檢索時,b+樹可以用name來指定搜尋方向,但下乙個欄位age的缺失,所以只能把名字等於張三的資料都找到,然後再匹配性別是f的資料了, 這個是非常重要的性質,即索引的最左匹配特性。
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索引原理
對於現在網際網路對資料庫的操作,都是查詢的使用比較多,雖說是使用了各種快取技術來儲存從資料看讀取的資料,但是資料在不停地更新,還是要不停地查詢資料庫,但是在查詢資料庫的時候對於io消耗特別大,所以能把查詢的io的操作次數降低,那對於資料庫的效能提公升是很明顯的,因此b tree就出現了 對於b tr...