亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

關于面試中常問的數據庫回表問題

 更新時間:2023年07月14日 09:36:27   作者:Wis57  
這篇文章主要介紹了關于面試中常問的數據庫回表問題,回表就是先通過數據庫索引掃描出數據所在的行,再通過行主鍵id取出索引中未提供的數據,即基于非主鍵索引的查詢需要多掃描一棵索引樹,需要的朋友可以參考下

什么是回表?為什么需要回表?

小伙伴們在面試的時候,有一個特別常見的問題,那就是數據庫的回表。

索引結構

要搞明白這個問題,需要大家首先明白 MySQL 中索引存儲的數據結構。這個其實很多小伙伴可能也都聽說過,B+Tree 嘛!

B+Tree 是什么?那你得先明白什么是 B-Tree,來看如下一張圖:

在這里插入圖片描述

前面是 B-Tree,后面是 B+Tree,兩者的區(qū)別在于:

  • B-Tree 中,所有節(jié)點都會帶有指向具體記錄的指針;
  • B+Tree 中只有葉子結點會帶有指向具體記錄的指針。
  • B-Tree 中不同的葉子之間沒有連在一起;
  • B+Tree 中所有的葉子結點通過指針連接在一起。
  • B-Tree 中可能在非葉子結點就拿到了指向具體記錄的指針,搜索效率不穩(wěn)定;
  • B+Tree 中,一定要到葉子結點中才可以獲取到具體記錄的指針,搜索效率穩(wěn)定。

基于上面兩點分析,我們可以得出如下結論:

B+Tree 中,由于非葉子結點不帶有指向具體記錄的指針,所以非葉子結點中可以存儲更多的索引項,這樣就可以有效降低樹的高度,進而提高搜索的效率。

B+Tree 中,葉子結點通過指針連接在一起,這樣如果有范圍掃描的需求,那么實現(xiàn)起來將非常容易,而對于 B-Tree,范圍掃描則需要不停的在葉子結點和非葉子結點之間移動。

對于第一點,一個 B+Tree 可以存多少條數據呢?以主鍵索引的 B+Tree 為例(二級索引存儲數據量的計算原理類似,但是葉子節(jié)點和非葉子節(jié)點上存儲的數據格式略有差異),我們可以簡單算一下。

計算機在存儲數據的時候,最小存儲單元是扇區(qū),一個扇區(qū)的大小是 512 字節(jié),而文件系統(tǒng)(例如 XFS/EXT4)最小單元是塊,一個塊的大小是 4KB。

InnoDB 引擎存儲數據的時候,是以頁為單位的,每個數據頁的大小默認是 16KB,即四個塊。

基于這樣的知識儲備,我們可以大致算一下一個 B+Tree 能存多少數據。

假設數據庫中一條記錄是 1KB,那么一個頁就可以存 16 條數據(葉子結點);對于非葉子結點存儲的則是主鍵值+指針,在 InnoDB 中,一個指針的大小是 6 個字節(jié),假設我們的主鍵是 bigint ,那么主鍵占 8 個字節(jié),當然還有其他一些頭信息也會占用字節(jié)我們這里就不考慮了,我們大概算一下,小伙伴們心里有數即可:

16*1024/(8+6)=1170

即一個非葉子結點可以指向 1170 個頁,那么一個三層的 B+Tree 可以存儲的數據量為:

1170117016=21902400

可以存儲 2100萬 條數據。

在 InnoDB 存儲引擎中,B+Tree 的高度一般為 2-4 層,這就可以滿足千萬級的數據的存儲,查找數據的時候,一次頁的查找代表一次 IO,那我們通過主鍵索引查詢的時候,其實最多只需要 2-4 次 IO 操作就可以了。

大家先搞明白這個 B+Tree。

兩類索引

大家知道,MySQL 中的索引有很多中不同的分類方式,可以按照數據結構分,可以按照邏輯角度分,也可以按照物理存儲分,其中,按照物理存儲方式,可以分為聚簇索引和非聚簇索引。

我們日常所說的主鍵索引,其實就是聚簇索引(Clustered Index);主鍵索引之外,其他的都稱之為非主鍵索引,非主鍵索引也被稱為二級索引(Secondary Index),或者叫作輔助索引。

對于主鍵索引和非主鍵索引,使用的數據結構都是 B+Tree,唯一的區(qū)別在于葉子結點中存儲的內容不同:

主鍵索引的葉子結點存儲的是一行完整的數據。

非主鍵索引的葉子結點存儲的則是主鍵值。

這就是兩者最大的區(qū)別。

所以,當我們需要查詢的時候:

如果是通過主鍵索引來查詢數據,例如 select * from user where id=100,那么此時只需要搜索主鍵索引的 B+Tree 就可以找到數據。

如果是通過非主鍵索引來查詢數據,例如 select * from user where username=‘javaboy’,那么此時需要先搜索 username 這一列索引的 B+Tree,搜索完成后得到主鍵的值,然后再去搜索主鍵索引的 B+Tree,就可以獲取到一行完整的數據。

對于第二種查詢方式而言,一共搜索了兩棵 B+Tree,第一次搜索 B+Tree 拿到主鍵值后再去搜索主鍵索引的 B+Tree,這個過程就是所謂的回表。

從上面的分析中我們也能看出,通過非主鍵索引查詢要掃描兩棵 B+Tree,而通過主鍵索引查詢只需要掃描一棵 B+Tree,所以如果條件允許,還是建議在查詢中優(yōu)先選擇通過主鍵索引進行搜索。

一定會回表嗎?那么不用主鍵索引就一定需要回表嗎?

不一定!

如果查詢的列本身就存在于索引中,那么即使使用二級索引,一樣也是不需要回表的。

舉個例子,我有如下一張表:

在這里插入圖片描述

uname 和 address 字段組成了一個復合索引,那么此時,雖然這是一個二級索引,但是索引樹的葉子節(jié)點中除了保存主鍵值,也保存了 address 的值。

我們來看如下分析:

在這里插入圖片描述

可以看到,此時使用到了 uname 索引,但是最后的 Extra 的值為 Using index,這就表示用到了索引覆蓋掃描(覆蓋索引),此時直接從索引中過濾不需要的記錄并返回命中的結果,這一步是在 MySQL 服務器層完成的,并且不需要回表。

擴展

基于第一、二小節(jié)的分析,我們再來捋一捋為什么在數據庫中建議使用自增主鍵。

自增主鍵往往占用空間比較小,int 占 4 個字節(jié),bigint 占 8 個字節(jié)。由于二級索引的葉子節(jié)點存儲的就是主鍵,所以如果主鍵占用空間小,意味著二級索引的葉子節(jié)點將來占用的空間?。ㄩg接降低 B+Tree 的高度,提高搜索效率)。

自增主鍵插入的時候比較快,直接插入即可,不會涉及到葉子節(jié)點分裂等問題(不需要挪動其他記錄);而其他非自增主鍵插入的時候,可能要插入到兩個已有的數據中間,就有可能導致葉子節(jié)點分裂等問題,插入效率低(要挪動其他記錄)。

當然,這個是基于技術層面的討論,如果業(yè)務上無法使用自增主鍵或者有其他要求導致無法使用自增主鍵,那沒辦法,在滿足新要求的情況下重新選擇一個最佳實踐吧。

到此這篇關于關于面試中常問的數據庫回表問題的文章就介紹到這了,更多相關數據庫回表內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Dbeaver如何從一個數據庫復制表到另外一個數據庫

    Dbeaver如何從一個數據庫復制表到另外一個數據庫

    在數據庫管理中,導出表是一項常見操作,可以通過特定的工具或數據庫自帶的功能實現(xiàn),步驟包括:1.在數據庫管理軟件中找到需導出的表,右鍵選擇導出數據,2.選擇目標數據庫,并進行表映射設置,3.根據需求調整導出參數,4.執(zhí)行操作完成數據導出
    2024-10-10
  • 你也許連刪庫跑路都不會(delete、drop和truncate刪除數據)

    你也許連刪庫跑路都不會(delete、drop和truncate刪除數據)

    這篇文章主要給大家介紹了關于delete、drop和truncate刪除數據的方式,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-11-11
  • hadoop map-reduce中的文件并發(fā)操作

    hadoop map-reduce中的文件并發(fā)操作

    hadoop mapreduce最主要的應用是基于鍵值對的數據的運算,過濾,提取。但除此之外,我們可以順帶利用mapreduce高并發(fā)的特性做一些用常用方法難以處理的問題,比如大量數據,大量文件的并發(fā)讀寫
    2014-04-04
  • 如何使用navicat遠程連接openGauss

    如何使用navicat遠程連接openGauss

    公司要在openEuler系統(tǒng)中安裝openGauss數據庫,經過幾天的查資料,終于是安裝成功了,并且能在navicat中遠程連接使用,本文給大家介紹如何使用navicat遠程連接openGauss,感興趣的朋友跟隨小編一起看看吧
    2023-10-10
  • PostgreSQL8.3.3安裝方法

    PostgreSQL8.3.3安裝方法

    非安裝版的PostgreSQL8.3.3的首次使用經歷第一次用Postgre,已經是好多年以前了,隱約記得是在linux下邊,build半天,然后手動配置庫文件之類。
    2008-09-09
  • Redis和Memcache的區(qū)別總結

    Redis和Memcache的區(qū)別總結

    這篇文章主要介紹了Redis和Memcache的區(qū)別,用三個總結來說明Redis和Memcache的區(qū)別,需要的朋友可以參考下
    2014-05-05
  • 以前架征途時的合區(qū)的SQL語句代碼備份

    以前架征途時的合區(qū)的SQL語句代碼備份

    本來以為資料都是丟了的,今天整理移動硬盤時發(fā)現(xiàn)found.000這個目錄超大,進去一看,我的媽呀,資料都在這里了,這下可把我樂壞了,我趕緊把一些有用的都發(fā)上來先
    2008-08-08
  • Instagram提升PostgreSQL性能的五個技巧

    Instagram提升PostgreSQL性能的五個技巧

    這篇文章主要介紹了Instagram提升PostgreSQL性能的五個技巧,Instagram的數據庫一直由PostgreSQL支撐,經驗很具有參考性,需要的朋友可以參考下
    2015-04-04
  • neo4j創(chuàng)建數據庫以及導入csv文件內容圖文詳解

    neo4j創(chuàng)建數據庫以及導入csv文件內容圖文詳解

    這篇文章主要給大家介紹了關于neo4j創(chuàng)建數據庫以及導入csv文件內容的相關資料,Neo4j是一個基于圖形結構的NoSQL數據庫,它提供了一種高效的方式來管理和查詢大型復雜數據,需要的朋友可以參考下
    2023-11-11
  • 50條SQL查詢技巧、查詢語句示例

    50條SQL查詢技巧、查詢語句示例

    這篇文章主要介紹了50條SQL查詢技巧、查詢語句示例,本文以學生表、課程表、成績表、教師表為例,講解不同需求下的SQL語句寫法,需要的朋友可以參考下
    2015-06-06

最新評論