目錄
如果你想深入了解為什麼mysql可以快速的進行檢索資料,那麼你一定要來了解一下mysql的索引原理
你可以把索引理解為一本書的目錄,我們www.cppcns.com可以通過索引快速的找到我們需要的資料,大概就像下面這個圖,索引就像是右邊的二叉樹,每個節點指向具體的資料的實體地址,先通過二叉樹找到資料的位置,然後再去物理磁碟中獲取資料。
但是不同的二叉樹的特性不同,我們還要選擇合適的樹來作為索引,所以接下來就來學習一下各個樹的特性
二分查詢樹就是在陣列的基礎上,利用二分查詢技巧,將用到的中間節點,作為指標。這樣他的每個節點的左子樹的值都小於該節點的值,每個節點右子樹的值都大於該節點的值。在查詢元素時,我們於根節點進行對比後,就能每次近乎一半的去除掉查詢範圍,可以極大的加快查詢速度。
優點:插入方便,不必連續排列
利用樹的特新,查詢很方便
缺點:如果每次都是插入都是最大值,會導致其變成鍊錶,查詢複雜度增加
插入的元素越多,樹的高度就會高,導致查詢效能下降
相比於二叉樹來說,自平衡二叉樹會通過左旋或者右旋來保證左子樹跟右子樹的高度差不超過一。這就很好解決了二分查詢樹變成鍊錶的問題
但如果元素越多,樹的高度還是很容易變的很高,這會導致查詢效率變慢。為了解決這個問題,於是就出現了b樹。
b樹的最大不同就是不再限制乙個節點只有乙個節點,而是允許有多個節點,這就是多叉樹。並且b樹所有的葉子節點必須在同一層次,也就是它們具有相同的深度
例如乙個度為 d 的 b-tree,設其索引 n 個 key,則其樹高 h 的上限為 logn(n/2),檢索乙個 key,其查詢節點個數的漸進複雜度為 o(logn((n+1)/2))。從這點可以看出,b-tree 是乙個非常有效率的索引資料結構。
區域性性原理
而這種多個節點的結構,還可以很好的借助磁碟預讀的特性。
由於儲存介質的特性,磁碟本身訪問就比主存慢很多,再加上機械運動耗費,磁碟的訪問速度往往是主存的幾百分分之一,因此為了提高效率,要儘量減少磁碟 i/o。為了達到這個目的,磁碟往往不是嚴格按需讀取,而是每次都會預讀,即使只需要乙個位元組,磁碟也會從這個位置開始,順序向後讀取一定長度的資料放入記憶體。這樣做的理論依據是電腦科學中著名的區域性性原理:當乙個資料被用到時,其附近的資料也通常會馬上被使用。程式執行期間所需要的資料通常比較集中。由於磁碟順序讀取的效率很高(不需要尋道時間,只需很少的旋轉時間),因此對於具有區域性性的程式來說,預讀可以提高 i/o 效率。
在b樹中,將乙個節點的大小設為等於乙個頁,這樣每個節點只需要一次i/o就可以完全載入。為了達到這個目的,在實際實現b樹還需要使用如下技巧:
每次新建節點時,直接申請乙個頁的空間,這樣就保證乙個節點物理上也儲存在乙個頁裡,加之計算機儲存分配都是按頁對齊的,就實現了乙個節點只需一次i/o。
rqbrclfkhd但是 b 樹的每個節點都包含資料(索引+記錄),而使用者的記錄資料的大小很有可能遠遠超過了索引資料,這就需要花費更多的磁碟 i/o 操作次數來讀到「有用的索引資料。而且,在我們查詢位於底層的某個節點(比如 a 記錄)過程中,「非 a 記錄節點」裡的記錄資料會從磁碟載入到記憶體,但是這些記錄資料是沒用的,我們只是想讀取這些節點的索引資料來做比較查詢,而「非 a 記錄節點」裡的記錄資料對我們是沒用的,這樣不僅增多磁碟 i/o 操作次數,也占用記憶體資源。
mysql普遍使用b+樹來實現其索引結構,跟b樹相比,b+樹有以下幾個不同點
葉子節點(最底部的節點)才會存放實際資料(索引+記錄),非葉子節點只會存放索引;
所有索引都會在葉子節點出現,葉子節點之間構成乙個有序鍊錶;
非葉子節點的索引也會同時存在在子節點中,並且是在子節點中所有索引的最大(或最小)。
非葉子節點中有多少個子節點,就有多少個索引;
b+ 樹的非葉子節點不存放實際的記錄資料,僅存放索引,因此資料量相同的情況下,相比儲存即存索引又存記錄的 b 樹,b+樹的非葉子節點可以存放更多的索引,因此 b+ 樹可以比 b 樹更「矮胖」,查詢底層節點的磁碟 i/o次數會更少。
b+作為多叉樹,在有大量的冗餘節點,在進行刪除或者插入操作時都不會發生複雜的樹的變形。
在資料庫中,還在b+樹的基礎上進行優化,增加了順序訪問指標。做這個優化的目的是為了提高區間訪問的效能,例如如果要查詢 key 為從 18 到 49 的所有資料記錄,當找到 18 後,只需順著節點和指標順序遍歷就可以一次性訪問到所有資料節點,極大提到了區間查詢效率。
程式設計客棧而 b 樹沒有將所有葉子節點用鍊錶串聯起來的結構,因此只能通過樹的遍歷來完成範圍查詢,這會涉及多個節點的磁碟 i/o 操作,範圍查詢效率不如 b+ 樹。因此,存在大量範圍檢索的場景,適合使用 b+樹,比如資料庫。而對於大量的單個索引查詢的場景,可以考慮 b 樹,比如 nosql 的mongodb。
而在mysql中,b+ 樹的葉子節點之間是用「雙向鍊錶」進行連線,這樣的好處是既能向右遍歷,也能向左遍歷
聚集索引(主鍵索引):將資料與索引放到了一塊,索引結構的葉子節點儲存了行資料,找到索引也就找到了資料
二級索引(非主鍵索引):將資料與索引分開儲存,索引結構的葉子節點儲存的是主鍵的值
innodrqbrclfkhdb 在建立聚簇索引時,會根據不同的場景選擇不同的列作為索引:
如果有主鍵,缺省會使用主鍵作為聚簇索引的索引鍵;
如果沒有主鍵,就選擇第乙個不包含 null 值的唯一列作為聚簇索引的索引鍵;
在上面兩個都沒有的情況下,innodb 將自動生成乙個隱式自增 id 列作為聚簇索引的索引鍵;
因為表的資料都是存放在聚集索引的葉子節點裡,所以 innodb 儲存引擎一定會為表建立乙個聚集索引,且由於資料在物理上只會儲存乙份,所以聚簇索引只能有乙個,而二級索引可以建立多個。
例如圖中(id,k)值分別為(100,1)、(200,2)、(300,3)、(500,5)和(600,6)
查詢時的區別:
如果語句是select * from t where id=500,即主鍵查詢方式,則只需要搜尋id這棵b+樹;
如果語句是select * from t where k=5,即普通索引查詢方式,則需要先搜尋k索引樹,得到id的值為500,再到id索引樹搜尋一次。這個過程稱為回表。
也就是說,基於非主鍵索引的查詢需要多掃瞄一棵索引樹。因此,我們在應用中應該盡量使用主鍵查詢。
www.cppcns.com
MySql資料庫索引介紹
資料庫索引對我們來說是透明的,因為資料庫表建立索引前後,sql語句都可以正常執行,索引的運用只是資料庫引擎工作時候的優化手段。但是,這並不是說資料庫索引僅僅是資料庫設計開發人員和運維人員的事情,對於乙個測試人員,如果對資料庫中已有的索引有所了解,可以對測試過程中發現的涉及資料庫操作的問題進行深入分析...
MySQL 資料庫索引介紹
索引就是加快檢索表中資料的方法。資料庫的索引類似於書籍的索引。在書籍中,索引允許使用者不必翻閱完整個書就能迅速地找到所需要的資訊。在資料庫中,索引也允許資料庫程式迅速地找到表中的資料,而不必掃瞄整個資料庫。mysql好比跑車,而沒有設計和使用索引的mysql就想乙個人力三輪車,沒有索引的表 資料量在...
mysql資料庫索引的介紹
索引用來快速地尋找那些具有特定值的記錄,所有mysql索引都以b 樹的形式儲存。如果沒有索引,執行查詢時mysql必須從第乙個記錄開始掃瞄整個表的所有記錄,直至找到符合要求的記錄。表裡面的記錄數量越多,這個操作的代價就越高。如果作為搜尋條件的列上已經建立了索引,mysql無需掃瞄任何記錄即可迅速得到...