mysql學習(2)索引的本質

2019獨角獸企業重金招聘Python工程師標準>>> hot3.png

問題:SQL查詢慢怎么辦?

優化手段,加索引。

索引是幫助MYSQL高效的獲取數據的排好序數據結構。

問題:索引結構為什么使用Btree而不使用二叉樹,紅黑樹或者HASH結構?

c1c900521dc65abc769edf1a90221702c83.jpg

9bdde83b121476a9bb09735e4cfdf7063b6.jpg二叉樹的特性,右邊子節點的值大于父節點,且左邊子節點的值小于父節點

二叉樹:使用二叉樹來做索引的數據結構,當索引值遞增的時候,二叉樹也會不斷地增加右子節點 ,那么在查找索引的時候,所做的IO操作,等同于沒有索引逐行查找數據的IO操作。

041e22786014a84768a7309e4825a92d9cd.jpg

紅黑樹:平衡二叉樹。隨著數據量增大,樹的高度也會變高。2的N次方=數量量(假設100萬),那么N至少也是50,那么樹的高度也是50,如果數據在子葉節點上,那么至少要經過50次的IO操作,才能找到數據。

HASH:散列表結構,key不適合排序,而且數據是散列的分布的,不利于IO讀寫。

BTree:一個節點上,橫向擴展。即一個節點上,可以存儲多個元素(Degree),且每個元素,都可以有子節點,叫做多叉樹。

  • 度(Degree)-節點的數據存儲個數
  • 葉節點具有相同深度
  • 葉節點的指針為空
  • 節點中的數據KEY從左至右遞增排列

????以5階B樹舉例

88eb6adcbb4bf5d015405fe5089fd980bce.jpg

B+Tree(Btree變種)

  • 非葉子節點不存儲data,只存儲key,可以增大度(Degree)-節點的數據存儲個數
  • 葉子節點不存儲指針
  • 葉子節點增加了順序訪問指針,提高區間訪問的性能

以5階B+樹舉例

df500de3d868d992daa47ab83a791cba975.jpg

問題:Btree和B+Tree的區別?

  • Btree每個節點,都包含了key和data,而B+tree只有葉子節點保存了key和data,其他節點,只保存了key,方便增大度的個數
  • B+tree的葉子節點之間, 增加了指針,提高了查詢區間的性能,不需要像Btree一樣每次都從根節點開始查找
  • Btree中,父節點和葉子節點,關鍵字的字段值不會冗余,而B+tree會冗余的存儲關鍵的索引值,即父節點和葉子結點都存在相同的關鍵值

MyISAM索引實現(非聚集)

MyISAM索引文件和數據文件是分離的。它是針對建表的,而不是針對數據庫的,既同一個數據庫可以多種類型的表,myISAM和innoDB。

在mysql的文件件中,會發現一個表有三個文件:

  • test_table_myisam.frm?// 存儲表的結構,表的定義
  • test_table_myisam.MYD // 存儲表的數據
  • test_table_myisam.MYI?// 存儲表的索引文件

myisam存儲引擎是非聚集索引,所以在MYI的文件中,以B+tree的數據結構存儲了表的索引信息,而索引內容中的data,是指向數據的在MYD文件中的地址。

在myisam存儲引擎中,主鍵索引使用了B+tree,而輔助索引,非主鍵索引,也同樣根據字段的值,使用了B+tree結構來存儲。

innoDB索引實現(聚集)

  • 表數據文件本身就是按B+Tree組織的一個索引結構文件

? ? b656b75058059556a6e200e976f45f97d18.jpg

  • 聚集索引 定義:葉節點包含了完整的數據記錄
  • 為什么innoDB表必須有主鍵,并且推薦使用整形的自增主鍵?
  • 為什么非主鍵索引結構葉子節點存儲的是主鍵值?(一致性和節省存儲空間)

在mysql的文件件中,會發現一個表有兩個文件:

  • test_table_myisam.frm? // 存儲表的結構,表的定義
  • test_table_myisam.ibd? // 存儲表的索引+數據

在innoDB存儲引擎中,輔助索引、非主鍵索引都不是聚集索引。

5be26d62c77b716bc36f10e466aa0d68e26.jpg

問題:為什么B+tree比Btree快?

樹的高度h,影響了查找效率,因為從根節點開始,每次查找下一個節點,都可能需要一次IO讀寫。所以增加非葉子節點的度,可以有效提高查詢效率。而CPU從磁盤上讀取數據到內存中,最小單元是頁,一頁讀取的最小數據是4KB,而CPU一次IO,讀取的數據是一頁的整數倍,且最大值也有限制。而mysql在底層,設置的大小是16KB。所以B+TREE要把數據放在葉子節點,所以非葉子幾點,就可以增加更多的節點數。而Btree節點和數據是保存在一起的,所以非葉節點的節點數,要比B+tree少,樹的高度就比B+tree高。

問題:為什么MYSQL頁文件默認的配置是16KB?

我們假設一行的數據是1K,那我們一頁的數據,就能存儲16行數據,也就是一個葉節點可以存儲16條記錄;再來看非葉節點,假設ID是bigint類型,那么長度為8B,指針大小在InnoDB源碼中為64(6B),一共就是14B,那么一頁里面就可以存儲16K/14=1170個(主鍵+指針)

那么一顆高度為2的B+樹能存儲的數據為:1170*16=18720條,一顆高度為3的B+樹可以存儲1170*1170*16=21902400(千萬條)

原因就是16KB就足夠應對千萬條表記錄了。

問題:為什么innoDB表必須有主鍵,并且推薦使用整形的自增主鍵?

? ? ? ? ?使用innoBD存儲引擎時,要建立主鍵索引,如果我們沒有主動創建索引,那么innoDB會自動幫我們建立主鍵索引。innoDB會在我們創建的表里找一列唯一的,可以代表主鍵的字段來創建主鍵索引,如果沒有這樣的字段,innoDB會默認加一列字段,來創建主鍵索引。有點類似oracle中的rowId。為什么要推薦整形而且自增的字段當做主鍵?為什么建議使用整形類型,因為如果使用uuid作為主鍵索引,uuid類型比整數類型大,為了方便IO操作一次讀取4個頁的數據(mysql默認16KB,一頁是4KB),意味索引的非葉子節點上的關鍵字要比使用整數類型的關鍵字數量小,那么B+tree的高度就可能增加,那么讀取葉子節點上的數據的IO操作次數就增加了。那么查找的效率就低了。為什么要自增,因為當新紀錄插入時,主鍵自增的話,在B+tree中插入節點比較方便,而使用uuid為主鍵,新紀錄的uuid不一定比前面的uuid大,可能會將新紀錄插在靠前面的葉子節點中,葉子節點滿了,會取中間的關鍵字向上存放到父節點中,可能會造成樹的分裂,微觀上性能就比自增的差。

轉載于:https://my.oschina.net/xiaoyoung/blog/3041322

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/251869.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/251869.shtml
英文地址,請注明出處:http://en.pswp.cn/news/251869.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

bzoj4245: [ONTAK2015]OR-XOR

一道很有意思的題目。 先求一次前綴和,可以發現答案是 (sum[0] xor sum[x1])or(sum[x1] xor sum[x2])or(sum[x2] xor sum[x3])or……or(sum[m-1] xor sum[n]) 然后其實(a xor b)or b a or b 那么sum[0]0,可以把柿子變成 sum[x1] or sum[x2] o…

移動端常見的一些兼容性問題

1、安卓瀏覽器看背景圖片,有些設備會模糊。 是devicePixelRatio作怪,因為手機分辨率太小,如果按照分辨率來顯示網頁,這樣字會非常小,所以蘋果當初就把iPhone 4的960*640分辨率,在網頁里只顯示了480*320&…

go-變量

這次我們學習一下golang語言 gitee: go-study 定義 定義的變量或者函數必須用到(pakeage內的全局除外) var a int // 默認為0 var b string //默認為"" fmt.Printf("%d %q\n",a, s) 復制代碼直接定義可以不寫類型(int..)go會自行判斷 var a, b 3, 4 var …

CSS3:CSS3 文本效果

ylbtech-CSS3:CSS3 文本效果1.返回頂部 1、CSS3 文本效果 CSS3 文本效果 CSS3中包含幾個新的文本特征。 在本章中您將了解以下文本屬性: text-shadowbox-shadowtext-overflowword-wrapword-break瀏覽器支持 屬性 text-shadow4.010.03.54.09.5box-sha…

洛谷 P2296 尋找道路

題目描述 在有向圖G 中,每條邊的長度均為1 ,現給定起點和終點,請你在圖中找一條從起點到終點的路徑,該路徑滿足以下條件: 1 .路徑上的所有點的出邊所指向的點都直接或間接與終點連通。 2 .在滿足…

Feature Preprocessing on Kaggle

剛入手data science, 想著自己玩一玩kaggle,玩了新手Titanic和House Price的 項目, 覺得基本的baseline還是可以寫出來,但是具體到一些細節,以至于到能拿到的出手的成績還是需要理論分析的。 本文旨在介紹kaggle比賽到各種原理與技巧&#xf…

十天沖刺-04

昨天:完成了日歷界面的部署,并且能夠獲取到選中的日期 今天:完成根據日期查找消費記錄功能 問題:日歷界面占用屏幕太多,后期會進行調整轉載于:https://www.cnblogs.com/liujinxin123/p/10760254.html

構建Spring Boot程序有用的文章

構建Spring Boot程序有用的文章: http://www.jb51.net/article/111546.htm轉載于:https://www.cnblogs.com/xiandedanteng/p/7508334.html

如果您遇到文件或數據庫問題,如何重置Joomla

2019獨角獸企業重金招聘Python工程師標準>>> 如果您遇到Joomla站點的問題,那么重新安裝其核心文件和數據庫可能是最佳解決方案。 了解問題 這種方法無法解決您的所有問題。但它主要適用于由Joomla核心引起的問題。 運行Joomla核心更新后,這些…

數組初始化 和 vector初始化

int result[256] {0}; 整個數組都初始化為0 vector<int> B(length,1); 整個vector初始化為1 如果你定義的vector是這樣定義的&#xff1a; vector<int> B; 去初始化&#xff0c;千萬不要用&#xff1a; for(int i 0;i < length;i)B[i] 1; 這樣會數組越界&…

Genymotion模擬器拖入文件報An error occured while deploying the file的錯誤

今天需要用到資源文件&#xff0c;需要將資源文件拖拽到sd卡中&#xff0c;但老是出現這個問題&#xff1a; 資源文件拖不進去genymotion。查看了sd的DownLoad目錄&#xff0c;確實沒有成功拖拽進去。 遇到這種問題的&#xff0c;我按下面的思路排查問題&#xff1a; Genymotio…

激光炸彈(BZOJ1218)

激光炸彈&#xff08;BZOJ1218&#xff09; 一種新型的激光炸彈&#xff0c;可以摧毀一個邊長為R的正方形內的所有的目標。現在地圖上有n(N<10000)個目標&#xff0c;用整數Xi,Yi(其值在[0,5000])表示目標在地圖上的位置&#xff0c;每個目標都有一個價值。激光炸彈的投放是…

/usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.15 not found

解決錯誤呈現該錯誤的原因是當前的GCC版本中&#xff0c;沒有GLIBCXX_3.4.15&#xff0c;須要安裝更高版本。我們可以輸入&#xff1a;strings /usr/lib/libstdc.so.6 | grep GLIBCXX&#xff0c;查看當前的GCC版本&#xff0c;成果如下&#xff1a;GLIBCXX_3.4 GLIBCXX_3.4.1 …

用servlet設計OA管理系統時遇到問題

如果不加單引號會使得除變量和int類型的值不能傳遞 轉發和重定向的區別 轉發需要填寫完整路徑&#xff0c;重定向只需要寫相對路徑。原因是重定向是一次請求之內已經定位到了服務器端&#xff0c;轉發則需要兩次請求每次都需要完整的路徑。 Request和response在解決中文亂碼時的…

JDK源碼——利用模板方法看設計模式

前言&#xff1a; 相信很多人都聽過一個問題&#xff1a;把大象關進冰箱門&#xff0c;需要幾步&#xff1f; 第一&#xff0c;把冰箱門打開&#xff1b;第二&#xff0c;把大象放進去&#xff1b;第三&#xff0c;把冰箱門關上。我們可以看見&#xff0c;這個問題的答案回答的…

[Usaco2010 Mar]gather 奶牛大集會

1827: [Usaco2010 Mar]gather 奶牛大集會 Time Limit: 1 Sec Memory Limit: 64 MB Submit: 1129 Solved: 525 [Submit][Status][Discuss]Description Bessie正在計劃一年一度的奶牛大集會&#xff0c;來自全國各地的奶牛將來參加這一次集會。當然&#xff0c;她會選擇最方便的…

與TIME_WAIT相關的幾個內核參數

問題 公司用瀏覽器訪問線上服務一會失敗一會成功&#xff0c;通過ssh連接服務器排查時發現ssh也是這樣&#xff1b; 檢查 抓包后發現建立連接的請求已經到了服務器&#xff0c;但它沒有響應&#xff1b; 糾結了好久&#xff0c;后來在騰訊云技術支持及查了相關資料后發現是開啟…

View的繪制-layout流程詳解

目錄 作用 根據 measure 測量出來的寬高&#xff0c;確定所有 View 的位置。 具體分析 View 本身的位置是通過它的四個點來控制的&#xff1a; 以下涉及到源碼的部分都是版本27的&#xff0c;為方便理解觀看&#xff0c;代碼有所刪減。 layout 的流程 先通過 measure 測量出 Vi…

1-1、作用域深入和面向對象

課時1&#xff1a;預解釋 JS中的數據類型 number、string、 boolean、null、undefined JS中引用數據類型 object: {}、[]、/^$/、Date Function var num12; var obj{name:白鳥齊鳴,age:10}; function fn(){ console.log(勿忘初心方得始終&#xff01;) }console.log(fn);//把整…

茶杯頭開槍ahk代碼

;說明這個工具是為了茶杯頭寫的,F1表示換槍攻擊,F3表示不換槍攻擊,F2表示停止攻擊. $F1::loop{ GetKeyState, state, F2, Pif state D{break } Send, {l down}Send, {l up}sleep,10Send,{m down}Send,{m up} }return $F3::loop{ GetKeyState, state, F2, Pif state D{break }…