跳到主要內容

圖解MySQL索引(二)—為什麼使用B+Tree_網頁設計


※推薦評價好的iphone維修中心



擁有專業的維修技術團隊,同時聘請資深iphone手機維修專家,現場說明手機問題,快速修理,沒修好不收錢


失蹤人口回歸,近期換工作一波三折,耽誤了不少時間,從今開始每周更新~


索引是一種支持快速查詢的數據結構,同時索引優化也是後端工程師的必會知識點。各個公司都有所謂的MySQL"軍規",其實這些所謂的優化和規定,並不是什麼高深的技術,只是要求大家正確建立和使用索引而已。工欲善其事必先利其器,想要正確運用索引,需要了解其底層實現原理,本文將探索關於索引的"是什麼"以及"為什麼"。


MySQL中關於索引的概念有很多,為了避免混淆,在上一篇文章中關於索引在不同維度分類設計到的一些名詞進行了解釋,如輔助索引,唯一索引,覆蓋索引,B+Tree索引…., 牆裂建議不明白的小夥伴可以先去看看圖解MySQL索引(上)—聊聊索引的分類,本文中關於索引類型的各種定義不再複述。


一,磁盤IO問題



1.1 磁盤IO



所謂磁盤IO,簡單來講就是就是將磁盤中的數據讀取到內存或者是從內存寫入磁盤。在系統開發與設計過程中,磁盤IO的瓶頸往往不可忽略,因為這是一個相對比較耗時的操作。


上圖是一個机械硬盤,雖然速度不如SSD,但是由於價格低廉,目前仍是主流的存儲介質。它的IO操作通常需要尋道,旋轉和傳輸三個步驟。


尋道,是指將讀寫磁頭移動到正確的磁道,尋道時間越短,IO操作越快,目前磁盤的平均尋道時間一般在3-15ms左右。


旋轉,是指將盤片旋轉到請求數據所在的扇區,這部分所需要的時間由硬盤的配置所決定。旋轉延遲由磁盤轉速所決定,也就是常說的7200轉和5400轉等。


例如,7200轉是指每分鐘可以旋轉7200圈,那麼旋轉一圈所需要的時間就是60*1000/7200 ≈ 8.33ms,而旋轉延遲通常取旋轉一周時間的1/2,也就是大約4.17ms。


傳輸,磁盤傳輸的速度通常在幾十到上百M每秒,假設速度為20M/s,要傳輸的數據為64kb,則傳輸時間則是 64 / 1024 / 20 * 1000 = 3.125ms。不過目前流行的SSD傳輸速度大幅度提升,SATA Ⅱ可以達到300M/s,傳輸速度往往遠小於前兩步操作所以傳輸時間往往可以忽略不記。


机械硬盤的連續讀寫性能很好,但隨機讀寫性能很差,這主要是因為磁頭移動到正確的磁道上需要時間,隨機讀寫時,磁頭需要不停的移動,時間都浪費在了磁頭尋址上,所以性能不高。


上述過程是對傳統机械磁盤IO延遲的粗略介紹,目的是告訴大家磁盤IO過程是個耗時的過程,內存操作往往與之速度不在同一個數量級。即使是目前比較流行的SSD,想必內存中數據讀取性能也差之千里。



1.2 局部性原理



由於磁盤IO是一個比較耗時的操作,而操作系統在設計時則定義一個空間局部性原則,局部性原理是指CPU訪問存儲器時,無論是存取指令還是存取數據,所訪問的存儲單元都趨於聚集在一個較小的連續區域中


在操作系統的文件系統中,數據也是按照page劃分的,一般為4k或8k。當計算機訪問一個地址數據時,不僅會加載當前數據所在的數據頁,還會將當前數據頁相鄰的數據頁一同加載到內存。而這個過程實際上只發生了1次磁盤IO,這個理論對於索引的數據結構設計非常有幫助。


二,索引數據結構演進


索引是一種支持快速查找的數據結構,在運用中往往還要求能夠支持順序查詢,而常見的數據結構有很多,比如數組,鏈表,二叉樹,散列表,二叉搜索樹,平衡搜索二叉樹,紅黑樹,跳錶等。僅僅從數據結構那麼為什麼選擇B+Tree呢?


首先對於數組,鏈表這種線性表來說,適合存儲數據,而不是查找數據,同樣,對於普通二叉樹來說,數據存儲沒有特定規律,所以也不適合。



2.1 哈希索引不能滿足業務需求



哈希(Hash)是一種非常快的查找方法,在一般情況下這種查找的時間複雜度為O(1),即一般僅需要一次查找就能定位到數據。在各種編程語言和數據庫中應用廣泛,如Java,Python,Redis中都有使用。


哈希結構在單條數據的等值查詢是性能非常優秀,但是只能用來搜索等值的查詢, 對於範圍查詢,模糊查詢(最左前綴原則)都不支持,所以不能很好的支持業務需求;所以MySQL並沒有顯式支持Hash索引,而是根據數據的訪問頻次和模式自動的為熱點數據頁建立哈希索引,稱之為自適應哈希索引。


並且由於哈希函數的隨機性,Hash索引通常都是隨機的內存訪問,對於緩存不友好,會造成頻繁的磁盤IO。



2.2 二叉搜索樹退化成鏈表



二叉搜索樹,如果左子樹不為空,則左子樹上所有節點均小於根節點,右子樹節點均大於根節點;由其屬性不難看出,這種樹非常適合數據查找。不過有個致命的缺點是二叉搜索樹的樹型取決於數據的輸入順序,極端情況下會退化成鏈表。



2.3 平衡二叉搜索樹過於嚴格



為了解決上述問題,平衡二叉搜索樹就誕生了。在保證數據順序的基礎上,又能維持樹型,保證每個節點的左右子樹高度相差不超過1。


網頁設計最專業,超強功能平台可客製化



窩窩以「數位行銷」「品牌經營」「網站與應用程式」「印刷品設計」等四大主軸,為每一位客戶客製建立行銷脈絡及洞燭市場先機。



不過由於要維持樹的平衡,在插入數據時可能要進行大量的數據移動。平衡搜索二叉樹過於嚴格的平衡要求,導致幾乎每次插入和刪除節點都會破壞樹的平衡性,使得樹的性能大打折扣。



2.4 紅黑樹高度過高,磁盤IO次數頻繁



有沒有一種數據結構,即能夠快速查找數據,又不需要頻繁的調整以維持平衡呢?這時紅黑樹就閃亮登場了。


紅黑樹和其他二叉搜索樹類似, 都是在進行插入和刪除操作時通過特定操作保持二叉查找樹的性質,從而獲得較高的查找性能。與之不同的是,紅黑樹的平衡性並不像平衡搜索二叉樹一樣嚴格的同時,又能保證在, O(log n) 時間複雜度內做查找和刪除。


紅黑樹通過改變節點的顏色,可以有效減少節點的移動次數,由於紅黑樹的實現比較複雜,本文不再展開,感興趣的小夥伴可以去深入學習。


看似紅黑樹是一種完美的數據結構,能夠勝任索引的工作。但MySQL並未使用其作為索引的實現,主要原因在於紅黑樹的深度過大,數據檢索時造成磁盤IO頻繁,假設一個每個節點存儲在一個page中,樹的高度為10,則每次檢索可能就需要進行10次磁盤IO。



2.5 B-Tree不支持順序查詢



B-Tree是一種自平衡的多叉搜索樹,一個節點可以擁有兩個以上的子節點。適合讀寫相對大的數據塊的存儲系統,例如磁盤。


由於MySQL索引一般都存儲在內存中,如果使用B-Tree作為索引的話,索引和數據存儲在一塊,分佈在各個節點中;而內存資源往往比較寶貴,一定內存的情況下可以存儲的索引數量相對有限,畢竟每條數據的大小一般遠大於索引列的大小,導致內存使用率不高。


數據查詢過程中往往會有順序查詢,而B-Tree和紅黑樹對於順序查詢並不友好



2.6 為什麼選B+Tree



B+Tree是在B-Tree基礎上演進而來的。與之不同的是B+Tree的數據頁只存儲在恭弘=叶 恭弘子節點中,並且恭弘=叶 恭弘子節點之間通過指針相連,為雙向鏈表結構。


B+Tree的優點可以分為以四個:



  1. 充分利用空間局部性原理,適合磁盤存儲。


  2. 樹的高度很低,能夠在存儲大量數據情況下,進行較少的磁盤IO【見下文介紹】。


  3. 能夠很好支持單值,範圍查詢,有序性查詢。


  4. 索引和數據分開存儲,讓更多的索引存儲在內存中。



三,MySQL中索引實現



3.1 巧妙利用B+Tree



MySQL中的數據存儲通常以Page為單位,俗稱數據頁,每個Page對應B+Tree的一個節點。頁是InnoDB磁盤管理的最小單位,默認每個數據頁的大小為16kb,也可以通過參數innodb_page_size將頁的大小設置成其他值。


數據庫的頁大小和操作系統類似,是指存放數據時,每一塊連續區域數據的大小。比如一個1M的數據存放在數據庫中時, 需要大概64個頁來存放(1024=64*16)。如果是在操作系統上安裝的數據庫,最好將數據庫頁大小設置為操作系統頁大小的倍數,才是最佳設置。



3.2 樹的高度-有效減少磁盤IO次數



通常情況下,一張MySQL表中有成千上萬條數據,而磁盤IO次數往往與數的高度成正比。默認情況下一個Page的大小為16kb,由於每個Page中數據通過指針相連,且每個指針大小為6字節。


在工作中,我們通常使用長度為8個字節的bigint類型作為主鍵id的類型。已知,每一條數據都會包含一個6字節的指針(數據頁中每條記錄都有指向下一條記錄的指針,但是沒有指向上一條記錄的指針);所以一條索引數據大約佔用8+6=14個字節,一個Page中能存儲16 * 1024 / 14 ≈ 1170條索引數據。高度為2的B+Tree大約能存儲1170*16 = 18720條這樣的記錄。同理,高度為3的B+Tree的B+Tree大約能存儲1170 * 1170 * 16 = 21902400,大約兩千萬條數據。 (每個節點大約能存儲1170條記錄,可以理解為此時B+Tree為1170叉樹)


例如,要檢索id=008的數據,則需要進行三次磁盤IO找到對應的數據頁(最多三次,因為Page可能在緩存中),然後在數據頁中進行二分查找,定位到對應的記錄。


四,總結


大家耳熟能詳的B+Tree索引是一種非常優秀的數據結構,也是面試熱點問題。本文從數據結構和磁盤IO兩個方面分析了為什麼使用B+Tree,以及MySQL的InnoDB存儲引擎的索引實現。在筆者面試過程中,被問到MySQL索引時通常也是從底層數據結構特點以及結合磁盤IO兩個角度去分析,屢試不爽。


學習一門技術時,我們不僅要知道其優點更要了解其缺點和瓶頸。在分析MySQL索引的實現時,不妨試試從其他數據結構的缺點入手!在Redis中使用跳錶實現了有序集合Zset,同樣支持高效的順序查詢,對比MySQL索引實現,跳錶能否替換B+Tree?如果不行,是因為什麼呢?

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

台北網頁設計公司這麼多該如何選擇?



網動是一群專業、熱情、向前行的工作團隊,我們擁有靈活的組織與溝通的能力,能傾聽客戶聲音,激發創意的火花,呈現完美的作品




Orignal From: 圖解MySQL索引(二)—為什麼使用B+Tree_網頁設計

留言

這個網誌中的熱門文章

旅館疑有臭蟲 北市府稽查找嘸

有民眾抱怨,日前投宿的北市某旅館疑似出現臭蟲,北市觀傳局與衛生局、環保局聯合稽查,但因為沒有發現蟲屍,無法確認該旅館是否真有臭蟲,市府下周將召開專家會議處理該案,市長蔣萬安則允諾會以最高規格防範臭蟲。 北市某旅館傳出疑有臭蟲,議員陳宥丞23日在市政總質詢詢問市府處理進度,並指出法國、澳洲、韓國的臭蟲,起初都現蹤公車或地鐵卻沒被發現,直到大規模爆發,才付出大量社會成本處理,而且一般殺蟲劑無法殺掉臭蟲,北市是否有因應措施? 觀傳局主任祕書蕭君杰表示,21日聯合環保局、衛生局到該旅館稽查,但沒有發現臭蟲,也沒有查到蟲卵跡象,只能檢查現場環境是否符合衛生相關規定,但環保局有指導業者如何針對臭蟲清潔消毒。觀傳局長王秋冬指出,下周會與專家學者召開會議,以最高規格處理此案。 想知道購買電動車哪裡補助最多? 台中電動車 補助資訊懶人包彙整 ;推薦評價好的 iphone維修 中心擁有專業的維修技術團隊,同時聘請資深iphone手機維修專家,現場說明手機問題,快速修理,沒修好不收錢住家的頂樓裝 太陽光電 聽說可發揮隔熱功效一線推薦東陽能源擁有核心技術、產品研發、系統規劃設置、專業團隊的太陽能發電廠商。 網頁設計 一頭霧水該從何著手呢? 回頭車 貨運收費標準宇安交通關係企業,自成立迄今,即秉持著「以誠待人」、「以實處事」的企業信念 台中搬家公司 教你幾個打包小技巧,輕鬆整理裝箱!還在煩惱搬家費用要多少哪?台中大展搬家線上試算搬家費用,從此不再擔心「物品怎麼計費」、「多少車才能裝完」 台中搬家 公司費用怎麼算?擁有20年純熟搬遷經驗,提供免費估價且流程透明更是5星評價的搬家公司好山好水 露營車 漫遊體驗露營車x公路旅行的十一個出遊特色。走到哪、玩到哪,彈性的出遊方案,行程跟出發地也可客製 廣告預算用在刀口上, 台北網頁設計 公司幫您達到更多曝光效益; 電動車補助 衛生局疾病管制科長張惠美表示,現場查到與臭蟲無關的多項衛生缺失,包含未提供從業人員體檢報告、簡易外傷藥品及器材超過有效期、紗窗有破損等,已要求業者2周內改善,將擇期複查,如果複查不合格,將依法裁罰3000元至2萬元罰鍰。 但陳宥丞批評,環保局未公告哪些藥劑能殺死臭蟲,很擔心北市會和韓國、法國一樣,把臭蟲防治交給民間恐造成大規模爆發,且北市內的廢棄傢俱回收廠也有可能成為臭蟲孳生的...

必知必會-存儲器層次結構

相信大家一定都用過各種存儲技術,比如mysql,mongodb,redis,mq等,這些存儲服務性能有非常大的區別,其中之一就是底層使用的存儲設備不同。作為一個程序員,你需要理解存儲器的層次結構,這樣才能對程序的性能差別瞭然於心。今天帶大家了解下計算機系統存儲器的層次結構。 存儲技術 首先了解下什麼是存儲器系統? 實質上就是一個具有不同容量、成本和訪問時間的存儲設備的層次結構。從快到慢依次為:CPU寄存器、高速緩存、主存、磁盤; 這裏給大家介紹一組數據,讓大家有一個更清晰的認識: 如果數據存儲在CPU寄存器,需要0個時鐘周期就能訪問到,存儲在高速緩存中需要4~75個時鐘周期。如果存儲在主存需要上百個周期,而如果存儲在磁盤上,大約需要幾千萬個周期! -- 出自 CSAPP 接下來一起深入了解下計算機系統涉及的幾個存儲設備: 隨機訪問存儲器 隨機訪問存儲器(RAM)分為靜態RAM (SRAM) 和動態RAM(DRAM)。SRAM的速度更快,但也貴很多,一般不會超過幾兆字節,通常用來做告訴緩存存儲器。DRAM就是就是我們常說的主存。 訪問主存 數據流是通過操作系統中的總線的共享电子電路在處理器和DRAM之間來來回回。每次CPU和主存之間的數據傳送都是通過一系列複雜的步驟完成,這些步驟成為總線事務。讀事務是將主存傳送數據到CPU。寫事務從CPU傳送數據到主存。 總線是一組并行的導線,能攜帶地址、數據和控制信號。下圖展示了CPU芯片是如何與主存DRAM連接的。 那麼我們在加載數據和存儲數據時,CPU和主存到底是怎樣交互實現的呢? 首先來看一個基本指令,加載內存數據到CPU寄存器中: movq A,%rax 將地址A的內容加載到寄存器%rax中,這個命令會使CPU芯片上稱為總線接口(bus interface)的電路在總線上發起讀事務,具體分為三個步驟: CPU將地址A放到系統總線上,I/O橋將信號傳遞到內存總線。詳情看下下圖a 主存感覺到內存總線上的地址信號,從內存總線讀地址,從DRAM取出數據字,將其寫到內存總線。I/O橋將內存總線信號翻譯成系統總線信號,沿着系統總線傳遞到CPU總線接口。下圖b CPU感覺到系統總線上的數據,從總線上讀數據,並將數據複製到寄存器%rax...

2016年電動車和插電式混合動力車銷量預計將超過70萬輛

中汽協日前預測,2016年全國電動汽車和插電式混合動力車的銷量預計將超過70萬輛,較2015年的銷量增長一倍。 2015年電動車和插電式混合動力車的合併銷量為331092輛,較2014年增長了340%。其中包括247482輛電動車和83610輛插電式混合動力車,在24萬輛多的電動汽車銷量中,包括146719輛乘用車,另有100763輛為商用車。插電式混合動力車的銷量中,60663輛為乘用車,22947輛為商用車。 根據2015年起草的藍圖,政府計畫到2020年在全國範圍內新建12000個充電站和480枚充電樁。2014年年底,全國共有780個充電站共31000枚充電樁。2015年政府還為27個省市自治區設定了電動車的最低銷量目標。 政府預計,這些措施到位後,自主品牌車企的電動車和插電式混合動力車銷量到2020年可達100萬輛,到2025年可達300萬輛。 本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理 【其他文章推薦】 ※為什麼 USB CONNECTOR 是電子產業重要的元件? ※ 網頁設計 一頭霧水??該從何著手呢? 找到專業技術的 網頁設計公司 ,幫您輕鬆架站! ※想要讓你的商品成為最夯、最多人討論的話題? 網頁設計公司 讓你強力曝光 ※想知道最厲害的 台北網頁設計公司推薦 、 台中網頁設計公司推薦 專業設計師"嚨底家"!! Orignal From: 2016年電動車和插電式混合動力車銷量預計將超過70萬輛