InnoDB索引概述,二分查找法,平衡二叉樹


索引是應用程序設計和開發的一個重要方面。如果索引太多,應用的性能可能會受到影響;如果索引太少,對查詢性能又會產生影響。要找到一個合適的平衡點,這對應用的性能至關重要。

如果知道數據的使用,從一開始就應該在需要處添加索引。開發人員對於數據庫的工作往往停留在應用的層面,比如編寫SQL語句、存儲過程之類,他們甚至可能不知道索引的存在,或者認為事后讓相關DBA加上即可。而DBA往往不了解業務的數據流,添加索引需要通過監控大量的SQL語句,從中找到問題。這個步驟需要的時間肯定是大於初始添加索引所需要的時間,並且可能會遺漏一部分索引。當然索引不是越多越好,某台MySQL服務器iostat顯示磁盤使用率100%,經過分析后發現,是由於開發人員添加了太多的索引。在刪除一些不必要的索引之后,磁盤使用率馬上下降為20%,因此索引的添加也是有一定技巧的。

InnoDB存儲引擎索引概述

InnoDB存儲引擎支持兩種常見的索引,一種是B+樹索引,另一種是哈希索引。InnoDB存儲引擎支持的哈希索引是自適應的,InnoDB存儲引擎會根據表的使用情況自動為表生成哈希索引,不能人為干預是否在一張表中生成哈希索引。

B+樹索引就是傳統意義上的索引,這是目前關系型數據庫系統中最常用、最有效的索引。B+樹索引的構造類似於二叉樹,根據鍵值(Key Value)快速找到數據。需要注意的是,B+樹中的B不是代表二叉(binary),而是代表平衡(balance,因為B+樹是從最早的平衡二叉樹演化而來,但是B+樹不是一個二叉樹。

一個常常被DBA忽視的問題是:B+樹索引並不能找到一個給定鍵值的具體行。B+樹索引能找到的只是被查找數據行所在的頁然后數據庫通過把頁讀入內存,再在內存中進行查找,最后得到查找的數據。

二分查找法

二分查找法(binary search)也稱為折半查找法,用來查找一組有序的記錄數組中的某一記錄。其基本思想是:記錄按有序化(遞增或遞減)排列,查找過程中采用跳躍式方式查找,即先以有序數列的中點位置為比較對象,如果要找的元素值小於該中點元素,則將待查序列縮小為左半部分,否則為右半部分。通過一次比較,將查找區間縮小一半

例如我們有5、10、19、21、31、37、42、48、50、52這10個數,現要從這10個數中查找48這條記錄,其查找過程如圖5-1所示。

從上圖可以看出,用了3次就找到了48這個數。如果是順序查找的話,則需要8次。因此二分查找法的效率比順序查找法要好(平均來說)。但如果查5這條記錄,順序查找只需1次,而二分查找法卻需要4次。對於上面10個數來說,順序查找的平均查找次數為(1+2+3+4+5+6+7+8+9+10)/10=5.5次,而二分查找法為(4+3+2+4+3+1+4+3+2+3)/10=2.9次。在最壞的情況下,順序查找的次數為10,而二分查找的次數為4。

二分查找法的應用極其廣泛,而且它的思想易於理解。第一個二分查找算法早在1946年就出現了,但是第一個完全正確的二分查找算法直到1962年才出現。每頁Page Directory中的槽是按照主鍵的順序存放的,對於某一條具體記錄的查詢是通過對Page Directory進行二分查找得到的

平衡二叉樹

在介紹B+樹前,先要了解一下二叉查找樹。B+樹是通過二叉查找樹,再由平衡二叉樹、B樹演化而來。

二叉查找樹是一種經典的數據結構。下圖顯示了一顆二叉查找樹。 

圖中的數字代表每個節點的鍵值,二叉查找樹中,左子樹的鍵值總是小於根的鍵值右子樹的鍵值總是大於根的鍵值

因此可以通過中序遍歷得到鍵值的排序輸出,中序遍歷后輸出:2、3、5、6、7、8。

對圖的這顆二叉樹進行查找,如查鍵值為5的記錄,先找到根,其鍵值是6,6大於5,因此找6的左子樹,找到3;而5大於3,再找右子樹……一共找了3次。如果按2、3、5、6、7、8的順序來找同樣需要3次。用同樣的方法再找鍵值為8的這個記錄,這次用了3次查找,而順序查找時需要6次。計算平均查找次數可得:順序查找的平均查找次數為(1+2+3+4+5+6)/6=3.3次,二叉查找樹的平均查找次數為(3+3+3+2+2+1)/6=2.3次。二叉查找樹比順序查找快。

二叉查找樹可以任意構造,同樣的2、3、5、6、7、8這五個數字,也可以按照下圖所示的方式建立二叉查找樹。效率較低的一顆二叉查找樹。

上圖的平均查找次數為(1+2+3+4+5+5)/6=3.16次,和順序查找差不多。顯然這次二叉查找樹的效率就低了。

因此若想最大性能地構造一個二叉查找樹,需要這顆二叉查找樹是平衡的,因此引出了新的定義——平衡二叉樹,或稱為AVL樹。

平衡二叉樹的定義如下:首先符合二叉查找樹的定義,其次必須滿足任何節點的左右兩個子樹的高度最大差為1。平衡二叉樹對於查找的性能是比較高的,但不是最高的,只是接近最高性能。要達到最好的性能,需要建立一顆最優二叉樹,但是最優二叉樹的建立和維護需要大量的操作,因此我們一般只需建立一顆平衡二叉樹即可。

平衡二叉樹對於查詢速度的確很快,但是維護一顆平衡二叉樹的代價是非常大的,通常需要1次或多次左旋右旋來得到插入或更新后樹的平衡性。

當我們需要插入一個新的鍵值為9的節點時,需要做如下的變動。

這里通過一次左旋操作就將插入后的樹重新變為平衡的了。但是有的情況下可能需要多次旋轉:

除了插入操作,還有更新和刪除操作,不過這和插入沒有本質的區別,它們都是通過左旋或者右旋來完成的。因此對於一顆平衡二叉樹的維護是有一定開銷的,不過平衡二叉樹多用於內存結構對象中,因此維護的開銷相對較小。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM