精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

別再一知半解啦!索引其實(shí)就這么回事!

運(yùn)維 數(shù)據(jù)庫運(yùn)維
索引的概念基本所有人都會遇到過,就算沒有了解過數(shù)據(jù)庫中的索引,在生活中也不可避免的接觸到。比方說書籍的目錄,字典的查詢頁,圖書館的科目檢索等等。其實(shí)這些都是一種索引,并且所起到的作用大同小異。

[[330453]]

索引的概念基本所有人都會遇到過,就算沒有了解過數(shù)據(jù)庫中的索引,在生活中也不可避免的接觸到。比方說書籍的目錄,字典的查詢頁,圖書館的科目檢索等等。其實(shí)這些都是一種索引,并且所起到的作用大同小異。

而對于數(shù)據(jù)庫而言,只不過是將索引的概念抽象出來,讓建立索引的過程更為靈活而自由,從而可以在不同的場景下優(yōu)化數(shù)據(jù)庫的查詢效率。

索引在數(shù)據(jù)庫的實(shí)際應(yīng)用場景中十分普遍,數(shù)據(jù)庫的優(yōu)化也離不開對索引的優(yōu)化。同時,索引相關(guān)的知識也是面試高頻的考點(diǎn)之一,是應(yīng)試者理論結(jié)合現(xiàn)實(shí)最為直接的體現(xiàn)。

因此,本文將從基礎(chǔ)理論出發(fā),介紹 MySQL 按照邏輯角度的索引分類和實(shí)現(xiàn),通過數(shù)據(jù)結(jié)構(gòu)的實(shí)現(xiàn)原理闡述不同結(jié)構(gòu)對建立索引帶來的優(yōu)劣勢,同時針對物理存儲的方式對索引的組織特點(diǎn)和應(yīng)用場景進(jìn)行分析。最后根據(jù)不同的應(yīng)用場景盡可能的探究如何建立起高性能的索引。文章結(jié)構(gòu)如下:

 

1 概念

什么是索引

索引似乎并沒有十分明確的定義,更多的是一種定性的描述。簡單來講,索引就是一種將數(shù)據(jù)庫中的記錄按照特殊形式存儲的數(shù)據(jù)結(jié)構(gòu)。通過索引,能夠顯著地提高數(shù)據(jù)查詢的效率,從而提升服務(wù)器的性能。

專業(yè)一點(diǎn)來說呢,索引是一個排好序的列表,在這個列表中存儲著索引的值和包含這個值的數(shù)據(jù)所在行的物理地址。在數(shù)據(jù)庫十分龐大的時候,索引可以大大加快查詢的速度,這是因?yàn)槭褂盟饕罂梢圆挥脪呙枞韥矶ㄎ荒承械臄?shù)據(jù),而是先通過索引表找到該行數(shù)據(jù)對應(yīng)的物理地址然后訪問相應(yīng)的數(shù)據(jù)。

說起索引,其實(shí)并不是 MySQL 數(shù)據(jù)庫特有的機(jī)制,在關(guān)系型數(shù)據(jù)庫中都會有類似不同的實(shí)現(xiàn)。這里我們也只是討論 MySQL 數(shù)據(jù)庫中的索引實(shí)現(xiàn)。

事實(shí)上,說是 MySQL 的索引其實(shí)并不準(zhǔn)確。因?yàn)樵?MySQL 中,索引是在存儲引擎層而不是服務(wù)器層實(shí)現(xiàn)的。這意味著我們所討論的索引準(zhǔn)確來說是 InnoDB 引擎或 MyISAM 引擎或其它存儲引擎所實(shí)現(xiàn)的。

所以索引即便是在 MySQL 中也沒有統(tǒng)一的標(biāo)準(zhǔn),不同存儲引擎的所實(shí)現(xiàn)的索引工作方式也并不一樣。不是所有的存儲引擎都支持相同類型的索引,即便是多個引擎支持同一種類型的索引,其底層的實(shí)現(xiàn)也可能不同。

為什么需要索引

說了這么多,索引似乎就是給數(shù)據(jù)庫添加了一個「目錄頁」,能夠方便查詢數(shù)據(jù)。但是索引的作用就僅此而已了嗎,為什么需要大費(fèi)周章的建立并優(yōu)化索引?

說個題外話,我其實(shí)查字典從來都不喜歡查目錄頁,無論是查中文還是英文。因?yàn)橛X得那樣很慢,一個個找索引,效率很低。我習(xí)慣用的方式就是直接翻開字典,根據(jù)翻開的位置進(jìn)行前后調(diào)整。比方說我想找「醬 JIANG」字,會先隨機(jī)翻到一頁,可能是「F」開頭,在「J」前面,就往后翻一點(diǎn);如果隨機(jī)翻到「L」,那就往前翻一點(diǎn)。重復(fù)直至找到。

這大概就是類似于二分查找的方式,看起來好像是擺脫了索引的束縛,并且也能夠獲得比較高的查詢效率。但是其實(shí)轉(zhuǎn)念一想,在計算機(jī)的運(yùn)行處理中,「一個個找索引」這個過程其實(shí)非常快,不能跟我們手動比對偏旁部首的效率相提并論。同時,為什么我可以直接翻開字典根據(jù)字母進(jìn)行調(diào)整呢,這其實(shí)不就是因?yàn)槲业哪X子里存在一個大概的「索引表」,知道每個字母大概對應(yīng)于字典的哪一個位置。雖然是模糊的,但卻是真實(shí)存在的。(好不容易強(qiáng)行解釋了一波...)

如此一來,可以看出索引的一大好處是如其概念中所提及的,使用索引后可以不用掃描全表來定位某行的數(shù)據(jù),而是先通過索引表找到該行數(shù)據(jù)對應(yīng)的物理地址然后訪問相應(yīng)的數(shù)據(jù)。這樣的方式自然減少了服務(wù)器在響應(yīng)時所需要對數(shù)據(jù)庫掃描的數(shù)據(jù)量。

不僅如此,在執(zhí)行數(shù)據(jù)庫的范圍查詢時,若不使用索引,那么MySQL會先掃描數(shù)據(jù)庫的所有行數(shù)據(jù)并從中篩選出目標(biāo)范圍內(nèi)的行記錄,將這些行記錄進(jìn)行排序并生成一張臨時表,然后通過臨時表返回用戶查詢的目標(biāo)行記錄。這個過程會涉及到臨時表的建立和行記錄的排序,當(dāng)目標(biāo)行記錄較多的時候,會大大影響范圍查詢的效率。

所以當(dāng)添加索引時,由于索引本身具有的順序性,使得在進(jìn)行范圍查詢時,所篩選出的行記錄已經(jīng)排好序,從而避免了再次排序和需要建立臨時表的問題。

同時,由于索引底層實(shí)現(xiàn)的有序性,使得在進(jìn)行數(shù)據(jù)查詢時,能夠避免在磁盤不同扇區(qū)的隨機(jī)尋址。使用索引后能夠通過磁盤預(yù)讀使得在磁盤上對數(shù)據(jù)的訪問大致呈順序的尋址。這本質(zhì)上是依據(jù)局部性原理所實(shí)現(xiàn)的。

局部性原理:當(dāng)一個數(shù)據(jù)被用到時,其附近的數(shù)據(jù)也通常會馬上被使用。程序運(yùn)行期間所需要的數(shù)據(jù)通常比較集中。由于磁盤順序讀取的效率很高(不需要尋道時間,只需很少的旋轉(zhuǎn)時間) ,因此對于具有局部性的程序來說,磁盤預(yù)讀可以提高I/O效率。

磁盤預(yù)讀要求每次都會預(yù)讀的長度一般為頁的整數(shù)倍。而且數(shù)據(jù)庫系統(tǒng)將一個節(jié)點(diǎn)的大小設(shè)為等于一個頁,這樣每個節(jié)點(diǎn)只需要一次 I/O 就可以完全載入。這里的頁是通過頁式的內(nèi)存管理所實(shí)現(xiàn)的,概念在這里簡單提一嘴。

分頁機(jī)制就是把內(nèi)存地址空間分為若干個很小的固定大小的頁,每一頁的大小由內(nèi)存決定。這樣做是為了從虛擬地址映射到物理地址,提高內(nèi)存和磁盤的利用率。

所以呢,總結(jié)一下。索引的存在具有很大的優(yōu)勢,主要表現(xiàn)為以下三點(diǎn):

  • 索引大大減少了服務(wù)器需要掃描的數(shù)據(jù)量
  • 索引可以幫助服務(wù)器避免排序和臨時表
  • 索引可以將隨機(jī) I/O 變成順序 I/O

以上三點(diǎn)能夠大大提高數(shù)據(jù)庫查詢的效率,優(yōu)化服務(wù)器的性能。因此一般來說,為數(shù)據(jù)庫添加高效的索引對數(shù)據(jù)庫進(jìn)行優(yōu)化的重要工作之一。

不過,凡事都有兩面性。索引的存在能夠帶來性能的提升,自然在其它方面也會付出額外的代價。

索引本身以表的形式存儲,因此會占用額外的存儲空間;

索引表的創(chuàng)建和維護(hù)需要時間成本,這個成本隨著數(shù)據(jù)量增大而增大;

構(gòu)建索引會降低數(shù)據(jù)的修改操作(刪除,添加,修改)的效率,因?yàn)樵谛薷臄?shù)據(jù)表的同時還需要修改索引表;

所以對于非常小的表而言,使用索引的代價會大于直接進(jìn)行全表掃描,這時候就并不一定非得使用索引了。沒辦法,成年人的世界總是這么的趨利避害。

2 邏輯分類

從邏輯的角度來對索引進(jìn)行劃分的話,可以分為單列索引、全文索引、組合索引和空間索引。其中單列索引又可分為主鍵索引、唯一索引和普通索引。這里的邏輯可以理解為從 SQL 語句的角度,或者是從數(shù)據(jù)庫關(guān)系表的角度。下面就簡單介紹這些索引的作用和用法,以及在修改表的時候如何添加索引。

主鍵索引

即主索引,根據(jù)主鍵建立索引,不允許重復(fù),不允許空值;

主鍵:數(shù)據(jù)庫表中一列或列組合(字段)的值,可唯一標(biāo)識表中的每一行。

加速查詢 + 列值唯一(不可以有null)+ 表中只有一個

  1. ALTER TABLE 'table_name' ADD PRIMARY KEY pk_index('col'); 

唯一索引

用來建立索引的列的值必須是唯一的,允許空值。唯一索引不允許表中任何兩行具有相同的索引值。比方說,在 employee 表中職員的姓 name 上創(chuàng)建了唯一索引,那么就表示任何兩個員工都不能同姓。

加速查詢 + 列值唯一(可以有null)

  1. ALTER TABLE 'table_name' ADD UNIQUE index_name('col'); 

普通索引

用表中的普通列構(gòu)建的索引,沒有任何限制。

僅加速查詢

  1. ALTER TABLE 'table_name' ADD INDEX index_name('col'); 

全文索引

用大文本對象的列構(gòu)建的索引

  1. ALTER TABLE 'table_name' ADD FULLTEXT INDEX ft_index('col'); 

組合索引

用多個列組合構(gòu)建的索引,這多個列中的值不允許有空值。

多列值組成一個索引,專門用于組合搜索,其效率大于索引合并。

  1. ALTER TABLE 'table_name' ADD INDEX index_name('col1','col2','col3'); 

在對多列組合建立索引時,會遵循「最左前綴」原則。

最左前綴原則:顧名思義,就是最左優(yōu)先,上例中我們創(chuàng)建了 (col1, col2, col3) 多列索引,相當(dāng)于創(chuàng)建了 (col1) 單列索引,(col1, col2) 組合索引以及 (col1, col2, col3) 組合索引。

所以當(dāng)我們在創(chuàng)建多列索引時,要根據(jù)業(yè)務(wù)場景,將 where 子句中使用最頻繁的一列放在最左邊。

空間索引

對空間數(shù)據(jù)類型的字段建立的索引,底層可通過 R 樹實(shí)現(xiàn)。只不過使用較少,了解即可。

3 實(shí)現(xiàn)原理

我們知道,索引的底層本身就是通過數(shù)據(jù)結(jié)構(gòu)來進(jìn)行實(shí)現(xiàn)的。那么根據(jù)其底層的結(jié)構(gòu),常見的索引類型可分為哈希索引,BTree 索引,B+Tree 索引等。這里我們就主要來介紹這三種索引背后的實(shí)現(xiàn)機(jī)制。

哈希索引

顧名思義,哈希索引是通過哈希表實(shí)現(xiàn)的。哈希表的特點(diǎn)在之前的文章「九大數(shù)據(jù)結(jié)構(gòu)」中已經(jīng)詳細(xì)介紹過。通過哈希表的鍵值之間的對應(yīng)關(guān)系,能夠在查詢時精確匹配索引的所有列。哈希索引將所有的根據(jù)索引列計算出來的哈希碼存儲在索引中,同時將指向每個數(shù)據(jù)行的指針保存在哈希表中。

 

上圖是通過哈希索引查詢行數(shù)據(jù)的示意圖,可以發(fā)現(xiàn)哈希索引同樣會發(fā)生哈希沖突,并且是通過鏈地址法解決沖突的。當(dāng)發(fā)送沖突時,還需要對鏈表進(jìn)行遍歷對比,才能夠找到最終的結(jié)果。

在 MySQL 中,只有 Memory 存儲引擎顯式的支持哈希索引,而innodb是隱式支持哈希索引的。

這里的隱式支持是指,innodb引擎有一個特殊的功能 “自適應(yīng)哈希索引”,當(dāng)innodb注意到一些索引值被使用的非常頻繁時,且符合哈希特點(diǎn)(如每次查詢的列都一樣),它會在內(nèi)存中基于 B-Tree 索引之上再創(chuàng)建一個哈希索引。這樣就讓 BTree 索引也具有哈希索引的一些有點(diǎn)。這是一個完全自動的、內(nèi)部的行為。

由于哈希結(jié)構(gòu)的特殊性,其用于非常高的檢索效率,通過哈希函數(shù)的映射可以一步到位。但是同樣也是因?yàn)榻Y(jié)構(gòu)的特殊,導(dǎo)致哈希索引只適用于某些特定的場合。哈希索引的限制[1]:

不支持范圍查詢,比如 WHERE a > 5;只支持等值比較查詢,包括=、IN 、<=>

無法被用來避免數(shù)據(jù)的排序操作;因?yàn)榻?jīng)過了哈希函數(shù)的映射過程,使得丟失了哈希前后的大小關(guān)系,從而無法按照索引值的順序存儲。

不支持部分索引列的匹配查找,因?yàn)楣K饕冀K使用索引列的全部內(nèi)容來計算哈希值。例如在數(shù)據(jù)列 (A, B) 上建立哈希索引,如果查詢只有數(shù)據(jù)列 A,則無法使用該索引。

無法避免表掃描。因?yàn)楫?dāng)出現(xiàn)哈希沖突的時候,存儲引擎必須遍歷鏈表(拉鏈法)中所有的行指針,逐行進(jìn)行比較,直到找到所有符合條件的行。

哈希沖突很多的情況下,其索引維護(hù)的代價很高,并且性能并不一定會比 BTree 索引高。

BTree 索引

BTree 實(shí)際上是一顆多叉平衡搜索樹。從名字可以看出,BTree 首先是一顆多叉搜索樹,這意味著它是具有順序的;其次 BTree 還是平衡的,這意味著它的左右子樹高度差小于等于1。

事實(shí)上一顆 BTree 需要滿足以下幾個條件:

每個葉子結(jié)點(diǎn)的高度都是一樣的;

每個非葉子結(jié)點(diǎn)由 n-1 個 key 和 n 個指針 point 組成,其中 d<=n<=2d, key 和 point 相互間隔,結(jié)點(diǎn)兩端一定是 key;

葉子結(jié)點(diǎn)指針都為 null;

非葉子結(jié)點(diǎn)的key都是 [key, data] 二元組,其中 key 表示作為索引的鍵,data 為鍵值所在行的數(shù)據(jù);

一顆常見的BTree樹見下圖。

 

這是一顆三階的BTree,可通過鍵值的大小排序進(jìn)行數(shù)據(jù)的查詢和檢索,其中葉子節(jié)點(diǎn)的指針都為空,因此省略沒畫。從上圖可以發(fā)現(xiàn),BTree 的樹形狀相較于我們之前常見的二叉樹等結(jié)構(gòu),更為扁平和矮胖。

之所以這樣設(shè)計,還是跟磁盤讀取的特點(diǎn)有關(guān)。我們知道在建立索引時,也是需要占據(jù)物理空間的。而實(shí)際上當(dāng)數(shù)據(jù)量比較大的時候,索引文件的大小也十分嚇人。考慮到一個表上可能有多個索引、組合索引、數(shù)據(jù)行占用更小等情況,索引文件的大小可能達(dá)到物理盤中數(shù)據(jù)的1/10,甚至可達(dá)到1/3。

這就意味著索引無法全部裝入內(nèi)存之中。當(dāng)通過索引對數(shù)據(jù)進(jìn)行訪問時,不可避免的需要對磁盤進(jìn)行讀寫訪問。同時我們還知道,內(nèi)存的讀寫速度是磁盤的幾個數(shù)量級。因此在對索引結(jié)構(gòu)進(jìn)行設(shè)計時要盡可能的減少對磁盤的讀寫次數(shù),也就是所謂的磁盤 I/O 次數(shù)。

這也就是索引會采用 BTree 這種扁平樹結(jié)構(gòu)的原因,樹的層數(shù)越少,磁盤I/O的次數(shù)自然就越少。不僅如此,我們上面提到過磁盤預(yù)讀的局部性原理。根據(jù)這個原理再加上頁表機(jī)制,能夠在進(jìn)行磁盤讀取的時候更大化的提升性能。

BTree 相較于其它的二叉樹結(jié)構(gòu),對磁盤的 I/O 次數(shù)已經(jīng)非常少了。但是在實(shí)際的數(shù)據(jù)庫應(yīng)用中仍有些問題無法解決。

一是無法定位到數(shù)據(jù)行。通過 BTree 可以根據(jù)主鍵的排序定位出主鍵的位置,但是由于數(shù)據(jù)表的記錄有多個字段,僅僅定位到主鍵是不夠,還需要定位到數(shù)據(jù)行。雖然這個問題可以通過在 BTree 的節(jié)點(diǎn)中存儲數(shù)據(jù)行或者增加定位的字段,但是這種方式會使得 BTree 的深度大幅度提高,從而也導(dǎo)致 I/O 次數(shù)的提高。

二是無法處理范圍查詢。在實(shí)際的應(yīng)用中,數(shù)據(jù)庫范圍查詢的頻率非常高,而 BTree 只能定位到一個索引位置。雖然可以通過先后查詢范圍的左右界獲得,但是這樣的操作實(shí)際上無法很好的利用磁盤預(yù)讀的局部性原理,先后查詢可能會造成通過預(yù)讀取的物理地址離散,使得 I/O 的效率并不高。

三是當(dāng)數(shù)據(jù)量一大時,BTree的高度依舊會變得很高,搜索效率還是會大幅度的下降。

問題總是推動改進(jìn)的前提。基于以上的問題考慮,就出現(xiàn)了對 BTree 的優(yōu)化版本,也就是 B+Tree。

B+Tree索引

B+Tree 一看就是在 BTree 的基礎(chǔ)上做了改進(jìn),那么到底改變了什么呢。廢話不多說,先上圖。

 

上圖實(shí)際上是一種帶有順序索引的 B+Tree,與最基本的 B+Tree 的區(qū)別就在于葉子節(jié)點(diǎn)是否通過指針相連。一般數(shù)據(jù)庫中常用的結(jié)構(gòu)都是這種帶有順序索引的 B+Tree。后文探討的也都是帶順序索引的 B+Tree 結(jié)構(gòu)。

對比 BTree 和 B+Tree,我們可以發(fā)現(xiàn)二者主要在以下三個方面上的不同:

非葉子節(jié)點(diǎn)只存儲鍵值信息,不再存儲數(shù)據(jù)。

所有葉子節(jié)點(diǎn)之間都有一個鏈指針,指向下一個葉子節(jié)點(diǎn)。

數(shù)據(jù)都存放在葉子節(jié)點(diǎn)中。

看著 B+Tree,像不像是一顆樹與一個有序鏈表的結(jié)合體。因而其實(shí) B+Tree 也就是帶有樹和鏈表的部分優(yōu)勢。樹結(jié)構(gòu)使得有序檢索更為簡單,I/O 次數(shù)更少;有序鏈表結(jié)構(gòu)使得可以按照鍵值排序的次序遍歷全部記錄。

B+Tree 在作為索引結(jié)構(gòu)時能夠帶來的好處有:

一,I/O 次數(shù)更少。這是因?yàn)樯衔囊舱f過,BTree 的節(jié)點(diǎn)是存放在內(nèi)存頁中的。那么在相同的內(nèi)存頁大小(一般為4k)的情況下,B+Tree 能夠存儲更多的鍵值,那么整體樹結(jié)構(gòu)的高度就會更小,需要的 I/O 次數(shù)也就越小。

二,數(shù)據(jù)遍歷更為方便。這個優(yōu)勢很明顯是由有序鏈表帶來的。通過葉子節(jié)點(diǎn)的鏈接,使得對所有數(shù)據(jù)的遍歷只需要在線性的鏈表上完成,這就非常適合區(qū)間檢索和范圍查詢。

三,查詢性能更穩(wěn)定。這自然是由于只在葉子節(jié)點(diǎn)存儲數(shù)據(jù),所以所有數(shù)據(jù)的查詢都會到達(dá)葉子節(jié)點(diǎn),同時葉子節(jié)點(diǎn)的高度都相同,因此理論上來說所有數(shù)據(jù)的查詢速度都是一致的。

正是由于 B+Tree 優(yōu)秀的結(jié)構(gòu)特性,使得常用作索引的實(shí)現(xiàn)結(jié)構(gòu)。在 MySQL 中,存儲引擎 MyISAM 和 InnoDB 都分別以 B+Tree 實(shí)現(xiàn)了響應(yīng)的索引設(shè)計。

4 物理存儲

雖說 B+Tree 結(jié)構(gòu)都可以用在 MyISAM 和 InnoDB,但是這二者對索引的在物理存儲層次的實(shí)現(xiàn)方式卻不相同。InnoDB 實(shí)現(xiàn)的是聚簇索引,而 MyISAM 實(shí)現(xiàn)的卻是非聚簇索引。在介紹聚簇索引之前,我們需要先了解以下啥是佩奇,不對,是啥是「主鍵索引」和「輔助索引」。

其實(shí)概念很簡單。我們剛剛不是在講 B+Tree 的時候說過,樹的非葉子節(jié)點(diǎn)只存儲鍵值。沒錯就是這個鍵值,當(dāng)這個鍵值是數(shù)據(jù)表的主鍵時,那么所建立的就是主鍵索引;當(dāng)這個鍵值是其它字段的時候,就是輔助索引。因而可以得出,主鍵索引只能有一個,而輔助索引卻可以有很多個。

聚簇索引和非聚簇索引的區(qū)別也就是根據(jù)其對應(yīng)的主鍵索引和輔助索引的不同特點(diǎn)而實(shí)現(xiàn)的。

聚簇索引

說回聚簇索引。先丟個定義。

聚簇索引的主鍵索引的葉子結(jié)點(diǎn)存儲的是鍵值對應(yīng)的數(shù)據(jù)本身;輔助索引的葉子結(jié)點(diǎn)存儲的是鍵值對應(yīng)的數(shù)據(jù)的主鍵鍵值。

這句話的信息量挺大的。首先,分析第一句話,主鍵索引的葉子節(jié)點(diǎn)存儲的是鍵值對應(yīng)的數(shù)據(jù)本身。

我們知道,主鍵索引存儲的鍵值就是主鍵。那么也就是說,聚簇索引的主鍵索引,在葉子節(jié)點(diǎn)中存儲的是主鍵和主鍵對應(yīng)的數(shù)據(jù)。數(shù)據(jù)和主鍵索引是存儲在一起的,一起作為葉子節(jié)點(diǎn)的一部分。

然后,分析第二句話,輔助索引的葉子結(jié)點(diǎn)存儲的是鍵值對應(yīng)的數(shù)據(jù)的主鍵鍵值。

我們又知道,輔助索引存儲的鍵值是非主鍵的字段。那就也就是說,通過輔助索引,可以找到非主鍵字段對應(yīng)的數(shù)據(jù)行中的主鍵。

重點(diǎn)來了。當(dāng)然主鍵索引和輔助索引一結(jié)合,能干啥呢。當(dāng)直接采用主鍵進(jìn)行檢索時,可通過主鍵索引直接獲得數(shù)據(jù);而當(dāng)采用非主鍵進(jìn)行檢索時,先需要通過輔助索引來獲得主鍵,然后再通過這個主鍵在主鍵索引中找到對應(yīng)的數(shù)據(jù)行。

舉個例子吧。假設(shè)有這么一個數(shù)據(jù)表。

 

那么采用聚簇索引的存儲方式,對應(yīng)的主鍵索引為:(主鍵為ID)

 

對應(yīng)的輔助索引為:(鍵值為Name,大概的意思):

 

所以當(dāng)使用where ID = 7這樣的條件查找主鍵,則按照B+樹的檢索算法即可查找到對應(yīng)的葉節(jié)點(diǎn),之后獲得行數(shù)據(jù)。對Name列進(jìn)行條件搜索,則需要兩個步驟:第一步在輔助索引B+樹中檢索Name,到達(dá)其葉子節(jié)點(diǎn)獲取對應(yīng)的主鍵。第二步使用主鍵在主鍵索引B+樹種再執(zhí)行一次B+樹檢索操作,最終到達(dá)葉子節(jié)點(diǎn)即可獲取整行數(shù)據(jù)。

最后把以上過程整理總結(jié)一下,聚簇索引實(shí)際上的過程就分為以下兩個過程。現(xiàn)在這個圖應(yīng)該能夠看懂了吧。

 

非聚簇索引

學(xué)完了聚簇索引,非聚簇索引就簡單多啦。同樣,先上定義。

非聚簇索引的主鍵索引和輔助索引幾乎是一樣的,只是主索引不允許重復(fù),不允許空值,他們的葉子結(jié)點(diǎn)都存儲指向鍵值對應(yīng)的數(shù)據(jù)的物理地址。

與聚簇索引來對比著看,上面的定義能夠說明什么呢。首先,主鍵索引和輔助索引的葉子結(jié)點(diǎn)都存儲著鍵值對應(yīng)的數(shù)據(jù)的物理地址,這說明無論是主鍵索引還是輔助索引都能夠通過直接獲得數(shù)據(jù),而不需要像聚簇索引那樣在檢索輔助索引時還得多繞一圈。

同時還說明一個點(diǎn),葉子結(jié)點(diǎn)存儲的是物理地址,那么表示數(shù)據(jù)實(shí)際上是存在另一個地方的,并不是存儲在B+樹的結(jié)點(diǎn)中。這說明非聚簇索引的數(shù)據(jù)表和索引表是分開存儲的。

同樣,對非聚簇索引的檢索過程來個總結(jié)。

 

無論是主鍵索引還是輔助索引的檢索過程,都只需要通過相應(yīng)的 B+Tree 進(jìn)行搜索即可獲得數(shù)據(jù)對應(yīng)的物理地址,然后經(jīng)過依次磁盤 I/O 就可訪問數(shù)據(jù)。

對比聚簇索引和非聚簇索引,可以發(fā)現(xiàn)二者最主要的區(qū)別就是在于是否在 B+Tree 的節(jié)點(diǎn)中存儲數(shù)據(jù),也就是數(shù)據(jù)和索引是否存儲在一起。這個區(qū)別導(dǎo)致最大的問題就是聚簇索引的索引的順序和數(shù)據(jù)本身的順序是相同的,而非聚簇索引的順序跟數(shù)據(jù)的順序沒有啥關(guān)系。

5 索引優(yōu)化

介紹了這么多的索引,其實(shí)最終都是為了建立高性能的索引策略,對數(shù)據(jù)庫中的索引進(jìn)行優(yōu)化。索引的優(yōu)化有很多角度,針對特定的業(yè)務(wù)場景可采用不同的優(yōu)化策略。這里考慮到文章篇幅,就不具體介紹,下次再出一篇專門講索引優(yōu)化的文章。簡單列舉一下在進(jìn)行優(yōu)化時可以考慮的幾個方向:

  • 1 獨(dú)立的列。索引列不能是表達(dá)式的一部分,也不能是函數(shù)的參數(shù)。
  • 2 前綴索引和索引選擇性。這二者實(shí)際上是相互制約的關(guān)系,制約條件在于前綴的長度。一般應(yīng)選擇足夠長的前綴以保證較高的選擇性(保證查詢效率),同時又不能太長以便節(jié)省空間。
  • 3 盡量使用覆蓋索引。覆蓋索引是指一個索引包含所有需要查詢的字段的值,這樣在查詢時只需要掃描索引而無須再去讀取數(shù)據(jù)行,從而極大的提高性能。
  • 4 使用索引掃描來做排序。要知道,掃描索引本身是很快的,在設(shè)計索引時,可盡可能的使用同一個索引既滿足排序,又滿足查找行數(shù)據(jù)。

最后,在建立索引時給幾個小貼士:

  • 1 優(yōu)先使用自增key作為主鍵
  • 2 記住最左前綴匹配原則
  • 3 索引列不能參與計算
  • 4 選擇區(qū)分度高的列作索引
  • 5 能擴(kuò)展就不要新建索引

6 總結(jié)

索引的概念和原理是我們在了解和精通數(shù)據(jù)庫過程中無法逃避的重點(diǎn),而事實(shí)上建立高性能的索引對實(shí)際的應(yīng)用場景也具有重要意義。本文的目的依舊是由淺入深的介紹索引這么個東西,從概念到實(shí)現(xiàn)再到最終的優(yōu)化策略。

點(diǎn)到為止,學(xué)無止境。掌握了基本的理論和概念后,還需要在實(shí)際的服務(wù)器開發(fā)場景中針對具體的問題和服務(wù)進(jìn)行索引優(yōu)化方案的設(shè)計和使用。功力不夠,仍需努力。

7 Reference

高性能 MySQL,Baron Schwartz 等人著,電子工業(yè)出版社

公眾號碼海系列文章

https://www.jianshu.com/p/9e9aca844c13

https://www.runoob.com/mysql/mysql-index.html

https://www.cnblogs.com/Aiapple/p/5693239.html

https://blog.csdn.net/tongdanping/article/details/79878302

https://www.cnblogs.com/igoodful/p/9361500.html

本文轉(zhuǎn)載自微信公眾號「 業(yè)余碼農(nóng)」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系 業(yè)余碼農(nóng)公眾號。

 

責(zé)任編輯:武曉燕 來源: 業(yè)余碼農(nóng)
相關(guān)推薦

2022-10-21 08:17:13

MongoDB查詢Document

2022-01-16 20:25:57

WebAssembly網(wǎng)絡(luò)

2020-03-04 08:47:10

Kafka架構(gòu)原理

2022-02-20 21:44:29

軟件系統(tǒng)架構(gòu)

2021-05-06 10:26:49

穩(wěn)定幣加密貨幣

2021-10-18 11:42:23

數(shù)據(jù)系統(tǒng)權(quán)衡

2020-03-09 09:56:13

高并發(fā)高可用架構(gòu)

2021-03-26 00:20:34

NFT區(qū)塊鏈數(shù)據(jù)庫

2020-02-04 18:27:38

人工智能倫理學(xué)一知半解

2022-11-16 12:48:38

2025-07-02 04:00:00

2024-02-05 08:35:32

VuenextTickDOM

2022-01-26 09:53:23

計算機(jī)體系結(jié)構(gòu)

2020-06-30 08:12:32

VMwareKVMDocker

2022-08-15 08:01:00

三色標(biāo)記JVM算法

2018-06-04 08:40:20

磁盤分區(qū)MBR

2021-07-29 16:56:59

微信騰訊注冊

2025-04-03 10:39:56

2023-05-31 16:40:01

2018-04-04 19:07:11

區(qū)塊鏈人工智能應(yīng)用場景
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

国产精品久久久久久久电影| 欧美精品18+| 鲁鲁狠狠狠7777一区二区| 男人天堂2024| 日韩综合一区| 精品国产一区二区三区忘忧草 | www.com污| 青春草在线视频| ww久久中文字幕| 成人av番号网| 欧美在线观看不卡| 99tv成人| 日韩国产欧美精品一区二区三区| xxx国产在线观看| 久久影院午夜精品| 国产精品久久久久久久浪潮网站| 国产一区二区三区免费不卡| 久久久久久av无码免费看大片| 欧美日本一区二区视频在线观看 | 美女看a上一区| 午夜精品一区二区三区在线播放| 2019男人天堂| 啪啪激情综合网| 91精品久久久久久久久99蜜臂| 成熟丰满熟妇高潮xxxxx视频| 日本高清中文字幕在线| xnxx国产精品| 国产伦精品一区二区| 91亚洲国产成人久久精品麻豆| 一本色道久久综合| 久久97精品久久久久久久不卡| 国产精品毛片一区二区| 亚洲伊人影院| 欧美一区二区三区人| 噼里啪啦国语在线观看免费版高清版| av有码在线观看| 亚洲女厕所小便bbb| 亚洲国产综合自拍| 久草视频在线看| www日韩大片| 久久精品aaaaaa毛片| 亚洲经典一区二区| 韩国v欧美v日本v亚洲v| 国产精品青青在线观看爽香蕉 | 麻豆福利在线观看| 1000部国产精品成人观看| 视频一区不卡| 好男人免费精品视频| 91色视频在线| 国产一区精品视频| 天天摸天天干天天操| 成人av网站在线观看免费| 7777精品久久久大香线蕉小说| 91免费视频播放| 久久精品99国产精品| 国产精品成人久久久久| 日本黄色中文字幕| 日韩中文字幕麻豆| 国产精品免费在线免费| 18国产免费视频| 欧美a级一区二区| 国产在线视频一区| 国产精品久久久久毛片| 精品在线你懂的| 91九色在线观看| 精品人妻一区二区三区四区不卡 | 国产美女久久久久久| 五月天综合网站| 理论片在线不卡免费观看| 美国黄色片视频| 亚洲一区二区三区无吗| 欧美大片在线免费观看| 国产在线观看免费av| 一本色道久久综合亚洲精品不卡 | 精品国模在线视频| 四虎精品免费视频| 狠色狠色综合久久| 2021国产精品视频| 久久久久久亚洲av无码专区| 老色鬼精品视频在线观看播放| 91精品国产综合久久香蕉最新版| 国产男女无套免费网站| 成人精品国产免费网站| 欧美一区二区三区电影在线观看| 成年人视频网站在线| 亚洲日本乱码在线观看| 国产高清av在线播放| 中文字幕乱码在线播放| 欧美人与z0zoxxxx视频| 超碰人人cao| 视频小说一区二区| 色哟哟亚洲精品一区二区| 男人操女人的视频网站| 99视频在线精品国自产拍免费观看| 日本成人精品在线| 国产一区二区三区在线观看| 成人教育av在线| 亚洲成人自拍视频| 欧美卡一卡二| 在线视频观看一区| 男插女视频网站| 日韩av三区| 色琪琪综合男人的天堂aⅴ视频| 久久久91视频| 日韩**一区毛片| 国产成人成网站在线播放青青| 日本aaa在线观看| 亚洲男人天堂一区| 久久久久久香蕉| 欧美经典一区| 中文字幕亚洲天堂| 日韩欧美大片在线观看| 蜜桃视频第一区免费观看| 国产精品免费视频一区二区| av女优在线| 精品国产91乱高清在线观看| 久久99爱视频| 一本色道久久综合亚洲精品酒店| 欧美精品免费在线观看| 成人一级免费视频| av电影天堂一区二区在线观看| 一区二区三区欧美在线| 成人av免费电影网站| 欧美成人三级电影在线| 国产极品视频在线观看| 国产日韩亚洲欧美精品| 99久热re在线精品996热视频| 999在线视频| 色悠悠亚洲一区二区| 91精品又粗又猛又爽| 99久久激情| 国产成人免费91av在线| 人妻一区二区三区四区| 亚洲精品国产a久久久久久| 污污网站在线观看视频| 欧洲福利电影| 国产成人福利视频| 日本福利片高清在线观看| 亚洲午夜成aⅴ人片| 99999精品| 久久久久久久久国产一区| 国产精品视频公开费视频| 高清福利在线观看| 色94色欧美sute亚洲13| 国产精品jizz| 久久夜色精品| 亚洲国产精品久久久久久女王| 日本欧美一区| 中文欧美在线视频| 精品乱码一区内射人妻无码 | 亚洲国产精品资源| 国产污片在线观看| 成人高清av在线| 国产中文字幕乱人伦在线观看| 成人h动漫免费观看网站| 欧美日本国产在线| 丰满肉肉bbwwbbww| 亚洲国产美女搞黄色| 国产真实乱人偷精品| aa国产精品| 麻豆精品蜜桃一区二区三区| 免费在线小视频| 亚洲男人天堂2019| 波多野结衣电影在线播放| 国产清纯在线一区二区www| 91在线视频观看免费| 91一区二区| 91超碰rencao97精品| 人妖欧美1区| 亚洲国产精品推荐| 色老头一区二区| 亚洲欧美一区二区在线观看| 国产精品999.| 亚洲精品一级| 亚洲精品一区二| 亚洲视频国产精品| 91高清免费在线观看| 91社区在线观看| 精品捆绑美女sm三区| www成人在线| 国产精品情趣视频| 26uuu国产| 亚洲在线黄色| 一本久道久久综合| 91成人福利| 国产精品h在线观看| 精品国产99久久久久久| 亚洲第一精品久久忘忧草社区| 中文字幕一区二区人妻视频| 亚洲人妖av一区二区| 亚洲一级av无码毛片精品| 日韩成人精品在线观看| 日本一区二区三区四区五区六区| 国产成人夜色高潮福利影视| 国产精品久久久久久久美男 | 91精品国产自产在线观看永久∴| 国产一区二区久久久| 色999久久久精品人人澡69| 久久久久久国产精品久久| 黄色av网站在线| 精品国精品自拍自在线| 69av视频在线观看| 亚洲综合男人的天堂| 特级西西www444人体聚色 | 久久日韩视频| 精品无人区太爽高潮在线播放| 国产精品国产三级国产普通话对白| 婷婷开心激情综合| 国产精品嫩草影院俄罗斯| 久久久99免费| 午夜剧场免费看| 国模娜娜一区二区三区| 97在线播放视频| 黄色工厂这里只有精品| 一区二区三区国| 国产成人久久| 久久精品99| 国产96在线亚洲| 成人xxxxx| 九九热线视频只有这里最精品| 欧美丰满老妇厨房牲生活| 99re在线视频| 亚洲网站视频福利| 人妻无码中文字幕| 日韩免费电影一区| 96日本xxxxxⅹxxx17| 色哟哟国产精品| 午夜精品三级久久久有码| 亚洲综合网站在线观看| 91精品一区二区三区蜜桃| 欧美激情一区二区三区蜜桃视频| 波多野结衣福利| 成人天堂资源www在线| 一级片免费在线观看视频| 国产真实乱对白精彩久久| 182午夜在线观看| 日本欧美韩国一区三区| 欧美日韩亚洲一| 国产日韩1区| 91猫先生在线| 亚洲在线视频| 免费在线激情视频| 先锋影音久久久| 激情五月开心婷婷| 久热综合在线亚洲精品| av观看免费在线| 久久久久免费| www.超碰com| 青青草91视频| 夜夜夜夜夜夜操| 黄色资源网久久资源365| 日韩欧美中文在线视频| 国产一区二区久久| 精品人妻人人做人人爽夜夜爽| 国产一区二区在线视频| 亚洲精品在线网址| 国产精品中文字幕欧美| www.成人黄色| 国产剧情av麻豆香蕉精品| 毛片毛片毛片毛片毛| 国产精品亚洲第一| 99riav国产精品视频| 成人免费看的视频| 第四色在线视频| 久久影音资源网| 天天舔天天操天天干| 最好看的中文字幕久久| 国产精品99精品| 色婷婷一区二区三区四区| 在线观看国产区| 欧美一级午夜免费电影| 丁香六月色婷婷| 亚洲人成绝费网站色www| 日本在线视频网| 国模叶桐国产精品一区| 国产日韩电影| 91精品视频在线| 红杏一区二区三区| 色视频一区二区三区| 日韩一区亚洲二区| 国产成人永久免费视频| 香蕉成人久久| 午夜免费一级片| 91免费国产在线观看| 久久久久久国产免费a片| 亚洲免费看黄网站| 成人精品免费在线观看| 欧美日本不卡视频| 天堂中文资源在线观看| 中文字幕亚洲欧美日韩在线不卡| 羞羞的视频在线观看| 2019亚洲男人天堂| 日韩亚洲国产免费| 国产日韩一区二区三区| 日韩精品久久| 男人天堂av片| 精品夜夜嗨av一区二区三区| 一区二区三区少妇| 最新不卡av在线| 无码一区二区三区在线观看| 日韩亚洲欧美一区| 成人不用播放器| 午夜精品福利电影| 色999韩欧美国产综合俺来也| 久久99精品国产99久久| 亚洲女同另类| 国产一区二区在线免费播放| 国产成人av电影免费在线观看| 日本一级免费视频| 亚洲一区二区美女| 在线观看黄色网| 日韩精品极品视频免费观看| 黄色在线论坛| 国产精品美女无圣光视频| 欧美人体视频| 亚洲一区 在线播放| 免费欧美在线视频| 91视频在线网站| 图片区小说区国产精品视频| 国产喷水吹潮视频www| 中文字幕av一区二区三区谷原希美| 九色porny丨入口在线| 97久草视频| 91成人免费| 在线免费看污网站| 国产精品欧美一区喷水| 欧美一区二区三区网站| 亚洲国产精品福利| 美女网站视频在线| av一区二区三区免费| 亚洲大全视频| 在线播放黄色av| 综合久久国产九一剧情麻豆| 中文字幕在线2019| 伊人久久久久久久久久久| 澳门av一区二区三区| 免费精品视频一区| 先锋a资源在线看亚洲| 国产制服丝袜在线| 大荫蒂欧美视频另类xxxx| 天堂中文资源在线观看| 97在线视频免费播放| 精品成人自拍视频| 成人在线观看你懂的| 成人av在线影院| 国产精品不卡av| 日韩高清a**址| 亚洲最大网站| 日本不卡一区二区三区在线观看| 另类国产ts人妖高潮视频| 国产真人做爰视频免费| 在线看一区二区| 色综合久久影院| 亚洲综合小说区| 国产精品99免费看| av免费观看不卡| 欧美日韩在线免费| 国产精品秘入口| 成人日韩av在线| 欧美日韩国内| 最近日本中文字幕| 色系网站成人免费| 香港伦理在线| 91九色露脸| 男人的天堂成人在线| 99久久久无码国产精品衣服| 欧美日韩在线三级| 99福利在线| 精品伊人久久大线蕉色首页| 视频一区二区国产| 日韩激情小视频| 亚洲国产精彩中文乱码av在线播放| 亚洲女同志freevdieo| 亚洲精品成人a8198a| 国产精品资源站在线| 欧美三级韩国三级日本三斤在线观看| 日韩成人网免费视频| 免费视频观看成人| 影音先锋成人资源网站| 91在线云播放| 一级片一区二区三区| 欧美高清视频一区二区| 亚洲警察之高压线| 中文字幕1234区| 黑人欧美xxxx| 含羞草www国产在线视频| 久久av免费一区| 秋霞av亚洲一区二区三| 久久亚洲AV无码| 亚洲网站在线播放| 成人av影音| 成年人三级黄色片| 色综合天天综合网天天看片| 黄网页免费在线观看| 欧美午夜精品理论片a级大开眼界 欧美午夜精品久久久久免费视 | 日韩黄色短视频| 国产精品福利一区二区三区| 手机在线精品视频| 成人动漫网站在线观看| 欧美中文日韩|