mysql索引原理深度解析


mysql索引原理深度解析

一、總結

一句話總結:

mysql索引是b+樹,因為b+樹在范圍查找、節點查找等方面優化 hash索引,完全平衡二叉樹,b樹等

 

1、數據庫中最常見的慢查詢優化方式是什么?

加索引

 

2、為什么加索引能優化慢查詢?

因為索引其實就是一種優化查詢的數據結構,比如mysql中的索引是用b+樹實現的,而b+樹就是一種數據結構

 

3、你知道哪些數據結構可以提高查詢速度?

哈希表,完全平衡二叉樹,b樹,b+樹等等

 

4、解決hash沖突的兩個方法?

鏈表法:沖突的放到一個鏈表上
再散列法:再次已經一次hash找位置

 

5、索引為什么能夠優化查詢?

因為索引用的b+樹,相比於一行一行的去找,肯定快很多

 

6、為什么mysql索引優化用的是b+樹,而不是hash索引?

hash索引查找速度非常快,但是不支持范圍查找,比如查找大於 某個數的,比如不支持查找大於 馬超的

 

7、為什么mysql索引優化用的是b+樹,而不是完全平衡二叉樹?

完全平衡二叉樹支持找范圍的,比如大於某個元素的:自己右孩子+父親的右孩子
b樹和b+樹高度低,找元素快:b樹和b+樹因為一個節點可以存多個元素,所以樹的高度比平衡二叉樹的高度要低,所以找元素要快(所以更少的磁盤io操作)

 

8、為什么mysql索引優化用的是b+樹,而不是b樹?

用空間換了時間,b+樹非葉子節點冗余進了葉子節點,b+樹葉子節點之間有指針,這樣找大於什么或者小於什么特別快

 

9、完全平衡二叉樹和b樹b+樹的區別是什么?

b樹b+樹一個節點里面可以存多個元素

 

10、b樹和b+樹的區別和聯系是什么?

b+樹節點是有冗余的,冗余的都是葉子節點,非葉子節點的數據都冗余在了葉子節點里面
b+樹的葉子節點之間用了指針聯系起來
b樹和b+樹節點里面都是有順序的,節點里面都是可以存多個元素的
b樹和b+樹的高度是一樣的,只是b+樹因為葉子節點要冗余非葉子節點,所以存的元素多一點而已

 

11、mysql中用b+樹的好處是什么?

找范圍的更快:比如我要做所有大於周瑜的,因為葉子節點之間有指針,並且非葉子節點的數據冗余在了葉子節點上,所以只用葉子節點一條鏈,就可以找到,非常快
樹高度低,找元素快:b樹和b+樹因為一個節點可以存多個元素,所以樹的高度比平衡二叉樹的高度要低,所以找元素要快(所以更少的磁盤io操作)

 

12、為什么考慮數據庫索引的結構的時候要考慮磁盤io的效率?

因為索引肯定是存在文件里面的,文件是存在磁盤里面的,所以讀索引肯定就涉及到了 磁盤io操作

 

13、磁盤io對數據庫索引查詢效率影響較大,給了我們什么啟示?

可以將數據從磁盤中讀入到內存中,避免頻繁的磁盤io訪問

 

14、b樹和b+樹一個節點中可以存多個元素,那么一個節點中存多少個元素好(節點的大小是多少好)?

頁的倍數:mysql中為16KB,是操作系統頁的4倍:這樣可以保證不浪費:因為操作系統一般都是以頁為最小單位取數據的
節點的大小如果 小於 操作系統頁的大小,會造成浪費
節點的大小如果 大於 操作系統頁的大小,也會造成浪費

 

15、mysql里面設置的一個節點的大小是多少?

去mysql配置文件中去看,可以發現 page_size(Innodb_page_size)的值是16384,也就是16kb,是操作系統頁的4倍,這是一個經驗值,操作系統一頁的大小一般是4kb

 

16、操作系統的局部性原理是什么?

比如你現在要去0x22這里取20B的數據,操作系統直接在這周圍取1kb的,你下次如果是取這周圍的數據(很大可能),我就可以直接在內存中取了,不用訪問數據庫了

 

17、mysql使用b+樹的時候,為什么只在葉子節點存data,而不在非葉子節點也存上data?

因為節點的大小固定的,比如16kb,那么每個節點里面存的元素的大小要越小越好,所以只在葉子節點處存data

 

18、innodb的數據和索引存在一起的好處是什么?

找索引的時候直接可以找到數據,省了一次磁盤io,不必根據索引再去磁盤io里面找數據

 

19、innodb表中你沒有寫主鍵,為什么也可以用?

因為innodb的索引和數據存在一起,所以你就算沒寫主鍵,沒有索引,innodb也會主動給你建一個的

 

20、mysql中b+樹的節點的大小是固定的16kb,為什么mysql的設計人員會選擇這個經驗值?

二層b+樹:找2次:存18724條數據
三層b+樹:找3次:存21907748:2200W條數據

 

21、mysql中高度為2的b+樹,可以存多少條數據?

葉子節點個數*16條=1170*16=18724條數據
一個葉子節點存16條數據:假設1條數據=1kb,葉子節點只存了數據,一個葉子節點里面可以存 16kb/1kb=16條數據
非葉子節點存1170個葉子節點:非葉子節點存了索引指針對:索引(bigint:8b)+指針(6b),所以可以存的對數為 16KB/14b=1170對

 

22、mysql中高度為3的b+樹,可以存多少條數據?

葉子節點個數*葉子節點個數*16條=1170*1170*16=21907748:2200W條數據
一個葉子節點存16條數據:假設1條數據=1kb,葉子節點只存了數據,一個葉子節點里面可以存 16kb/1kb=16條數據
非葉子節點存1170個葉子節點:非葉子節點存了索引指針對:索引(bigint:8b)+指針(6b),所以可以存的對數為 16KB/14b=1170對

 

23、如果有索引,mysql的2W條數據和2000W條數據的性能如何?

差不多,都是高度為3的b+樹

 

24、mysql中的聯合索引怎么存?

將聯合索引字段對應的數據連接起來合成一個整體,比如10110_teacher_30(字符串),然后以單索引的b+樹那么存

 

25、判斷mysql中的索引用到沒用到的實質是什么?

如果索引表限定了查詢范圍,就是用到了索引,比如要找到位1_23_aa,我發現索引b+樹的根節點為3-23-bb,那我就只用去左子樹里面去找了,這就是用到了索引

 

26、如何判斷聯合索引是否被用到了?

判斷用到了聯合索引字段的前面的字段:因為聯合索引是將聯合索引字段對應的數據連接起來合成一個整體,比如10110_teacher_30(字符串),然后以單索引的b+樹那么存,而字符串比較又是從字符串的前頭開始比較起的,所以如果判斷用到了聯合索引字段的前面的字段,就用到了索引

 

27、mysql如果我找數據有兩個索引,那么我用哪個?

mysql的查詢優化器會預估判斷你哪個索引花費小,就用哪個

 

28、mysql中explain select * from user where name is null用到索引了么?

用到了索引,mysql會把null存到索引的b+樹里面去,所以用到了索引

 

29、數據結構可視化網站?

https://www.cs.usfca.edu/~galles/visualization/Algorithms.html

 

30、mysql進階學習怎么學?

索引的原理與 使用
EXPLAIN 和 查詢優化器的使用
MYSQL 鎖機制
MYSQL 事務機制

 

 

 

 

二、內容在總結中

b+樹

b樹

 

mysql中b+樹

 

 


免責聲明!

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



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