最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Mysql數(shù)據(jù)庫(kù)索引面試題(程序員基礎(chǔ)技能)

 更新時(shí)間:2021年05月31日 10:03:07   作者:慕楓技術(shù)筆記  
索引是Mysql的一塊硬骨頭,但是對(duì)于程序猿來(lái)說(shuō)又是十分重要的基礎(chǔ)技能。本文將從索引原理、索引設(shè)計(jì)原則方面闡述Mysql索引,相信通過(guò)本文的學(xué)習(xí)你將完美征服阿里面試官

引言

索引是Mysql的一塊硬骨頭,但是對(duì)于程序猿來(lái)說(shuō)又是十分重要的基礎(chǔ)技能。在平常的項(xiàng)目開發(fā)中,它是重要的SQL優(yōu)化手段。在求職面試中,它是面試官常常用來(lái)考察求職者數(shù)據(jù)庫(kù)性能優(yōu)化方面的重要考量。因此透徹的掌握索引原理,并能夠?qū)⑵溥\(yùn)用到數(shù)據(jù)庫(kù)查詢實(shí)戰(zhàn)是每個(gè)程序猿必備的能力。本文將從索引原理、索引設(shè)計(jì)原則方面闡述Mysql索引。相信閱讀完本文之后,在Mysql索引查詢數(shù)據(jù)理解這塊完全可以征服阿里面試官。準(zhǔn)備好了嗎?我們發(fā)車了。

在這里插入圖片描述

索引原理

在進(jìn)行索引設(shè)計(jì)以及優(yōu)化之前,我們先深入理解下索引的原理。因?yàn)樗械脑O(shè)計(jì)以及優(yōu)化一定是建立在你對(duì)原理的透徹理解的基礎(chǔ)上。

很多人都知道,在進(jìn)行SQL查詢時(shí),同樣一張表、同樣的數(shù)據(jù)。不加索引以及加索引進(jìn)行數(shù)據(jù)查詢。兩者差別很多。那么到底是為什么有這種差距。簡(jiǎn)單來(lái)說(shuō),如果把業(yè)務(wù)數(shù)據(jù)比作為一本字典的話,那么索引就是這本字典的目錄。如果我讓你查一個(gè)字,在你不使用目錄查的時(shí)候,那只能一頁(yè)一頁(yè)的翻,運(yùn)氣不好的話可能要翻到最后一頁(yè)才能查到想要的字,這就是傳說(shuō)中的全表掃描。但是如果我們通過(guò)目錄來(lái)查找,那么可以很快定位字所在頁(yè),進(jìn)而查找到對(duì)應(yīng)的字。看到了吧,索引的威力就在于提高數(shù)據(jù)查詢的效率。好了,現(xiàn)在我們對(duì)于索引有了感性的認(rèn)識(shí)。那么我們接下來(lái)就深入了解下。

我們都知道在Mysql中索引的數(shù)據(jù)結(jié)構(gòu)是B+樹(這里不再說(shuō)明B樹、Hash索引等結(jié)構(gòu)的優(yōu)劣,不是本文的重點(diǎn)),那么我們就一步一步來(lái)看看,索引在磁盤中的B+樹是怎么長(zhǎng)成的。

1、數(shù)據(jù)頁(yè)

在日常的項(xiàng)目開發(fā)中,我們的業(yè)務(wù)數(shù)據(jù)大部分都存在關(guān)系型數(shù)據(jù)中。那么數(shù)據(jù)庫(kù)中各個(gè)表中的數(shù)據(jù)最終也都是存儲(chǔ)在服務(wù)器的硬盤當(dāng)中的。不知道大家有沒(méi)有想過(guò)這個(gè)數(shù)據(jù)到底是怎么存儲(chǔ)的呢?實(shí)際上Mysql數(shù)據(jù)庫(kù)中我們每天都在使用的數(shù)據(jù)庫(kù)表是對(duì)于人來(lái)理解的邏輯表。它實(shí)際在磁盤當(dāng)中是通過(guò)一頁(yè)頁(yè)的數(shù)據(jù)頁(yè)進(jìn)行存儲(chǔ)的。數(shù)據(jù)頁(yè)是磁盤與內(nèi)存交互的基本單位,MysqlInnodb存儲(chǔ)引擎,實(shí)際通過(guò)buffer pool與磁盤中的數(shù)據(jù)頁(yè)進(jìn)行交互,而不是直接操作磁盤中的數(shù)據(jù)頁(yè)。數(shù)據(jù)頁(yè)的結(jié)構(gòu)如下圖所示:

數(shù)據(jù)頁(yè)結(jié)構(gòu)

同時(shí)相鄰的數(shù)據(jù)頁(yè)之間通過(guò)雙向鏈表來(lái)維護(hù)數(shù)據(jù)頁(yè)之間的相互引用。如下圖所示,橙紅色部分即為數(shù)據(jù)頁(yè),中間的小框框可以理解為一條條具體的數(shù)據(jù)。MysqlInnoDB存儲(chǔ)引擎數(shù)據(jù)頁(yè)大小是16KB。MysqlInnodb存儲(chǔ)引擎通過(guò)頁(yè)號(hào)來(lái)唯一定位一個(gè)數(shù)據(jù)頁(yè),因此每個(gè)數(shù)據(jù)頁(yè)都有自己的頁(yè)號(hào)。通過(guò)上圖可知,每個(gè)數(shù)據(jù)頁(yè)都有都有對(duì)應(yīng)的Page Header,在Page Header中保存了當(dāng)前數(shù)據(jù)頁(yè)的頁(yè)號(hào),以及其下一頁(yè)的頁(yè)號(hào)和上一頁(yè)的頁(yè)號(hào)。

在這里插入圖片描述

相鄰的數(shù)據(jù)之間通過(guò)指針進(jìn)行互相引用,指針標(biāo)注數(shù)據(jù)頁(yè)的頁(yè)號(hào),每個(gè)數(shù)據(jù)頁(yè)中存儲(chǔ)了連續(xù)的一段數(shù)據(jù),每個(gè)數(shù)據(jù)行中的記錄頭部存有下一行記錄真實(shí)數(shù)據(jù)的地址偏移量,簡(jiǎn)單理解為擁有指針指向下一行數(shù)據(jù)的地址。因此在數(shù)據(jù)頁(yè)的內(nèi)部,實(shí)際是關(guān)于數(shù)據(jù)行的單向鏈表。這個(gè)單向鏈表是關(guān)于主鍵id的,從小到大進(jìn)行排列。

在這里插入圖片描述

從上述的數(shù)據(jù)頁(yè)結(jié)構(gòu)可知,每次進(jìn)行數(shù)據(jù)插入時(shí)User Records區(qū)域就會(huì)變大,相應(yīng)的的User Record區(qū)域就會(huì)減少。當(dāng)User Record區(qū)域消耗完之后,就會(huì)發(fā)生頁(yè)分裂,形成新的數(shù)據(jù)頁(yè)。這里需要注意的是,如果我們使用的是Mysql中的自增主鍵,那么可以保證按照id的增長(zhǎng)順序進(jìn)行數(shù)據(jù)行排列,但是如果主鍵是我們自己設(shè)置的并不是自增長(zhǎng)的,那么有可能出現(xiàn)后面插入的數(shù)據(jù)的主鍵值小于前面數(shù)據(jù)的主鍵值,那么在進(jìn)行頁(yè)分裂的時(shí)候,Mysql會(huì)按照主鍵大小重新進(jìn)行排列。此處不知道大家有沒(méi)有疑問(wèn),為什么一定要按照主鍵大小進(jìn)行排列呢?實(shí)際上和后續(xù)的數(shù)據(jù)查詢有關(guān)系,數(shù)據(jù)頁(yè)中的數(shù)據(jù)按照主鍵順序進(jìn)行排列是索引可以正常運(yùn)行的基礎(chǔ)。大致的過(guò)程如下圖所示:

在這里插入圖片描述

2、頁(yè)目錄

每個(gè)數(shù)據(jù)頁(yè)都有自己的頁(yè)目錄上面頁(yè)結(jié)構(gòu)中的Page Directory,這個(gè)頁(yè)目錄的作用實(shí)際上就是用來(lái)進(jìn)行數(shù)據(jù)行定位的。數(shù)據(jù)頁(yè)中的數(shù)據(jù)實(shí)際上是按組分配的,頁(yè)目錄中的不同的槽位,其實(shí)是對(duì)應(yīng)了數(shù)據(jù)頁(yè)中的不同的分組,查詢數(shù)據(jù)時(shí),通過(guò)id找到對(duì)應(yīng)的槽,再根據(jù)對(duì)應(yīng)的槽來(lái)知道對(duì)應(yīng)在數(shù)據(jù)頁(yè)中的數(shù)據(jù)行分組,遍歷數(shù)據(jù)行分組中的數(shù)據(jù)直到找到對(duì)應(yīng)的數(shù)據(jù)。

在這里插入圖片描述

3、索引原理分析

(1)索引基礎(chǔ)

有了上面兩節(jié)的數(shù)據(jù)頁(yè)的基礎(chǔ)知識(shí)之后,我們?cè)賮?lái)探討索引原理就更加容易理解了。在沒(méi)有索引時(shí),數(shù)據(jù)查詢都是進(jìn)行全表掃描。遍歷查詢數(shù)據(jù)頁(yè)中的每個(gè)數(shù)據(jù)行,再遍歷所有的數(shù)據(jù)頁(yè),知道找到符合條件的數(shù)據(jù)項(xiàng)。因此查詢效率十分的低下。那么應(yīng)該怎么才能提供數(shù)據(jù)查詢的效率呢?能不能像字典的目錄一樣,也搞個(gè)主鍵目錄來(lái)進(jìn)行數(shù)據(jù)頁(yè)號(hào)的定位呢?答案是肯定的,Mysql實(shí)際也正是這么做的。Mysql通過(guò)主鍵目錄實(shí)際就是傳說(shuō)中的主鍵索引,實(shí)現(xiàn)數(shù)據(jù)的查詢優(yōu)化。在主鍵目錄中包含了兩個(gè)重要元素,一個(gè)是數(shù)據(jù)頁(yè)中最小的主鍵,另一個(gè)是當(dāng)前數(shù)據(jù)頁(yè)的頁(yè)號(hào)。這樣可以通過(guò)這個(gè)主鍵目錄方面的進(jìn)行數(shù)據(jù)查詢。

舉個(gè)栗子,如果此時(shí)想要查詢主鍵id=5的數(shù)據(jù),那么首先在主鍵目錄中進(jìn)行查找。此時(shí)發(fā)現(xiàn)主鍵id=5大于主鍵id=1,但是又小于id=8,那么就可以確定實(shí)際上數(shù)據(jù)實(shí)際是在頁(yè)號(hào)為1的數(shù)據(jù)頁(yè)中的。

當(dāng)然在實(shí)際在Mysql中會(huì)有很多的數(shù)據(jù)頁(yè),因此對(duì)應(yīng)的主鍵索引也會(huì)很多,那么此時(shí)就需要通過(guò)二分查找的方式進(jìn)行數(shù)據(jù)頁(yè)定位,再查找到對(duì)應(yīng)的數(shù)據(jù)。

在這里插入圖片描述

(2)索引頁(yè)

如今當(dāng)下,各個(gè)互聯(lián)網(wǎng)公司迅猛發(fā)展,對(duì)應(yīng)的業(yè)務(wù)量也是十分巨大。因此數(shù)據(jù)庫(kù)中的數(shù)據(jù)量也是十分龐大的。表中的數(shù)據(jù)幾百萬(wàn)、上千萬(wàn)可能很常見,按照上述的主鍵目錄,那么就需要存儲(chǔ)大量的主鍵與數(shù)據(jù)頁(yè)號(hào)。即便是進(jìn)行二分查找,其數(shù)據(jù)查詢效率也是比較低的。

Mysql實(shí)際是將索引說(shuō)句存儲(chǔ)在索引頁(yè)中的,當(dāng)數(shù)據(jù)量比較大時(shí)候,對(duì)應(yīng)的索引也會(huì)比較多,因此通過(guò)專門的索引頁(yè)來(lái)存儲(chǔ)索引數(shù)據(jù)。另外在這些索引頁(yè)的上層又通過(guò)主鍵與索引頁(yè)號(hào)來(lái)繼續(xù)進(jìn)行索引頁(yè)的查詢定位,因此我們得到如下的結(jié)構(gòu)。其中的id號(hào)指的是對(duì)應(yīng)最小的id號(hào)。

在這里插入圖片描述

如果索引頁(yè)中的數(shù)據(jù)越來(lái)越多,索引頁(yè)同樣會(huì)進(jìn)行頁(yè)分裂。這樣索引頁(yè)也就形成了不同的層級(jí),索引頁(yè)層、索引頁(yè)、數(shù)據(jù)頁(yè)這三個(gè)頁(yè)數(shù)據(jù)就形成了我們說(shuō)的B+樹。下圖就是索引的B+樹結(jié)構(gòu),通過(guò)它完成數(shù)據(jù)查詢效率遠(yuǎn)高于全表掃描。B+的葉子節(jié)點(diǎn)才會(huì)存儲(chǔ)數(shù)據(jù),下圖是一種主鍵索引,也叫聚簇索引。其實(shí)我們可以看出來(lái),它的根本思想就是分而治之的思想。數(shù)據(jù)量很大是吧,那我就把數(shù)據(jù)分成很多的數(shù)據(jù)頁(yè),數(shù)據(jù)頁(yè)很多是吧,那我就通過(guò)索引頁(yè)來(lái)組織數(shù)據(jù)頁(yè),索引頁(yè)很多是吧,那就再通過(guò)索引頁(yè)來(lái)索引。

在這里插入圖片描述

我們?cè)賮?lái)看下,數(shù)據(jù)查詢?cè)?code>B+樹中的查詢過(guò)程。舉個(gè)栗子,如當(dāng)前需要查詢id為3的數(shù)據(jù),那么將在索引頁(yè)中判斷應(yīng)該走索引頁(yè)為3的索引頁(yè)。那么在索引頁(yè)為3中繼續(xù)判斷id=1應(yīng)該走索引頁(yè)為1的索引頁(yè),在索引頁(yè)中判斷應(yīng)該頁(yè)號(hào)為1的數(shù)據(jù)頁(yè),在此數(shù)據(jù)頁(yè)中遍歷最終查詢到對(duì)應(yīng)的數(shù)據(jù)。

在這里插入圖片描述

以上通過(guò)索引頁(yè)與數(shù)據(jù)頁(yè)組成的B+樹就是聚簇索引,當(dāng)然我們也可以通過(guò)其他字段來(lái)建立普通索引。知識(shí)普通索引會(huì)的葉子節(jié)點(diǎn)存儲(chǔ)的是對(duì)應(yīng)的主鍵id,而不是具體的數(shù)據(jù),索引會(huì)存在回表的問(wèn)題,即查詢到對(duì)應(yīng)的id之后,還需要根據(jù)id繼續(xù)到聚簇索引中查詢具體的數(shù)據(jù),通過(guò)這樣的操作才能查詢到select *的所有數(shù)據(jù)。當(dāng)然我們可以通過(guò)覆蓋索引的方式避免這樣的查詢浪費(fèi)。

總結(jié)

本文通過(guò)一步步圖解的方式,為大家拆解MysqlInnoDB的索引原理,同時(shí)構(gòu)建出對(duì)應(yīng)的B+樹索引結(jié)構(gòu)。闡述了數(shù)據(jù)查詢的具體過(guò)程。相信大家對(duì)于索引這塊有了更加深刻的理解,后面會(huì)從實(shí)戰(zhàn)的角度出發(fā),分析下如何設(shè)計(jì)索引以及如何應(yīng)對(duì)索引失效的問(wèn)題。

相關(guān)文章

  • MySQL和Redis之間的存儲(chǔ)區(qū)別

    MySQL和Redis之間的存儲(chǔ)區(qū)別

    MySQL是一種關(guān)系型數(shù)據(jù)庫(kù),而Redis是一種鍵值對(duì)存儲(chǔ)數(shù)據(jù)庫(kù),雖然它們都是用來(lái)存儲(chǔ)和管理數(shù)據(jù)的,但是它們?cè)诤芏喾矫娑加胁煌?,本文就給大家詳細(xì)介紹一下MySQL和Redis之間的存儲(chǔ)區(qū)別,感興趣的同學(xué)可以參考一下
    2023-06-06
  • MySQL 問(wèn)題匯總及常見解決方式

    MySQL 問(wèn)題匯總及常見解決方式

    文章總結(jié)了MySQL使用中常見的問(wèn)題及解決方案,包括連接與訪問(wèn)問(wèn)題、性能優(yōu)化、數(shù)據(jù)操作與語(yǔ)法問(wèn)題、服務(wù)與配置問(wèn)題和存儲(chǔ)引擎相關(guān)問(wèn)題,主要建議先查日志定位問(wèn)題,日常做好配置優(yōu)化和備份,遇到復(fù)雜問(wèn)題結(jié)合工具進(jìn)行分析,感興趣的朋友跟隨小編一起看看吧
    2017-09-09
  • Mysql分組排序取每組第一條的2種實(shí)現(xiàn)方式

    Mysql分組排序取每組第一條的2種實(shí)現(xiàn)方式

    開發(fā)中經(jīng)常會(huì)遇到,分組查詢最新數(shù)據(jù)的問(wèn)題,下面這篇文章主要給大家介紹了關(guān)于Mysql分組排序取每組第一條的2種實(shí)現(xiàn)方式,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-02-02
  • 在MySQL中修改密碼及訪問(wèn)限制的設(shè)置方法詳解

    在MySQL中修改密碼及訪問(wèn)限制的設(shè)置方法詳解

    MySQL是一個(gè)真正的多用戶、多線程SQL數(shù)據(jù)庫(kù)服務(wù)器。MySQL是以一個(gè)客戶機(jī)/服務(wù)器結(jié)構(gòu)的實(shí)現(xiàn),它由一個(gè)服務(wù)器守護(hù)程序mysqld和很多不同的客戶程序和庫(kù)組成。
    2007-03-03
  • mysql實(shí)現(xiàn)connect by start with方式

    mysql實(shí)現(xiàn)connect by start with方式

    本文介紹了MySQL中實(shí)現(xiàn)層級(jí)查詢的幾種方法,并分享了一種使用變量循環(huán)賦值的方式,通過(guò)實(shí)驗(yàn)驗(yàn)證了該方法的有效性
    2024-12-12
  • VMWare linux mysql 5.7.13安裝配置教程

    VMWare linux mysql 5.7.13安裝配置教程

    這篇文章主要為大家詳細(xì)介紹了VMWare linux mysql 5.7.13安裝配置教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • 一文帶你掌握MySQL中的連表查詢

    一文帶你掌握MySQL中的連表查詢

    在 MySQL 中,連表查詢是通過(guò)關(guān)聯(lián)多個(gè)表的共同字段整合數(shù)據(jù)的核心操作,本文將基于真實(shí)的業(yè)務(wù)表(用戶表、訂單表、商品表),詳細(xì)講解所有連表查詢類型的語(yǔ)法、作用、執(zhí)行結(jié)果,并對(duì)比彼此的核心差異,讓你直觀理解各類連表查詢的特點(diǎn)
    2026-01-01
  • MySQL性能瓶頸排查定位實(shí)例詳解

    MySQL性能瓶頸排查定位實(shí)例詳解

    這篇文章主要介紹了MySQL性能瓶頸排查定位的方法,結(jié)合實(shí)例形式詳細(xì)分析了MySQL排查性能瓶頸問(wèn)題的步驟與相關(guān)技巧,需要的朋友可以參考下
    2016-04-04
  • MySQL觸發(fā)器的應(yīng)用示例詳解

    MySQL觸發(fā)器的應(yīng)用示例詳解

    這篇文章主要介紹了MySQL觸發(fā)器的應(yīng)用,觸發(fā)器是與MySQL數(shù)據(jù)表有關(guān)的數(shù)據(jù)庫(kù)對(duì)象,在滿足定義條件時(shí)觸發(fā),并執(zhí)行觸發(fā)器中定義的語(yǔ)句集合,觸發(fā)器的這種特性可以協(xié)助應(yīng)用在數(shù)據(jù)庫(kù)端確保數(shù)據(jù)的完整性,需要的朋友可以參考下
    2022-08-08
  • MySQL?數(shù)據(jù)庫(kù)范式化設(shè)計(jì)理論總結(jié)

    MySQL?數(shù)據(jù)庫(kù)范式化設(shè)計(jì)理論總結(jié)

    這篇文章主要介紹了MySQL?數(shù)據(jù)庫(kù)范式設(shè)計(jì)理論總結(jié),數(shù)據(jù)庫(kù)的規(guī)劃化范式設(shè)計(jì),在邏輯結(jié)構(gòu)上可以讓結(jié)構(gòu)更加細(xì)粒度,容易理解,下文我們就來(lái)了解具體的內(nèi)容介紹吧
    2022-04-04

最新評(píng)論

娄底市| 连江县| 葫芦岛市| 林周县| 和林格尔县| 西充县| 西城区| 慈溪市| 盐山县| 哈密市| 北川| 井研县| 延长县| 揭西县| 蕲春县| 林西县| 射洪县| 来凤县| 介休市| 米脂县| 保山市| 康马县| 东海县| 太白县| 濉溪县| 芦山县| 营口市| 盐源县| 平遥县| 平度市| 汉中市| 洞头县| 遂溪县| 乌兰县| 建昌县| 武夷山市| 合作市| 张家口市| 宁国市| 新丰县| 德保县|