https://www.cnblogs.com/aspirant/p/9214485.html一步步分析為什么B+樹適合作為索引的結(jié)構(gòu) 以及索引原理mysql的B+樹索引 查找使用了二分查找,redis 跳表也使用了二分查找法,kafka查詢消息日志也使用了二分查找法,二分查找法時(shí)間復(fù)雜度O(logn); 參考:redis的索引底層的 跳表原理 實(shí)現(xiàn) 聊聊Mysql索引和redis跳表 ---redis的跳表原理 時(shí)間復(fù)雜度O(logn)(阿里) 參考:kafka如何實(shí)現(xiàn)高并發(fā)存儲(chǔ)-如何找到一條需要消費(fèi)的數(shù)據(jù)(阿里) 參考:二分查找法:各種排序算法的時(shí)間復(fù)雜度和空間復(fù)雜度(阿里) 在MySQL中,主要有四種類型的索引,分別為:B-Tree索引,Hash索引,F(xiàn)ulltext索引(MyISAM 表)和R-Tree索引,本文講的是B-Tree索引。 后面的索引原理一定要看,太重要了,阿里兩個(gè)人都問這個(gè)mysql的索引原理 mysql使用了 B+索引: B樹:有序數(shù)組+平衡多叉樹; 一、Mysql索引主要有兩種結(jié)構(gòu):B+Tree索引和Hash索引(a) Inodb存儲(chǔ)引擎 默認(rèn)是 B+Tree索引 (b) MyISAM 存儲(chǔ)引擎 默認(rèn)是Fulltext索引; (c)Memory 存儲(chǔ)引擎 默認(rèn) Hash索引; Hash索引 mysql中,只有Memory(Memory表只存在內(nèi)存中,斷電會(huì)消失,適用于臨時(shí)表)存儲(chǔ)引擎顯示支持Hash索引,是Memory表的默認(rèn)索引類型,盡管Memory表也可以使用B+Tree索引。Hash索引把數(shù)據(jù)以hash形式組織起來,因此當(dāng)查找某一條記錄的時(shí)候,速度非常快。但是因?yàn)閔ash結(jié)構(gòu),每個(gè)鍵只對(duì)應(yīng)一個(gè)值,而且是散列的方式分布。所以它并不支持范圍查找和排序等功能。
B+Tree索引 B+Tree是mysql使用最頻繁的一個(gè)索引數(shù)據(jù)結(jié)構(gòu),是Inodb和Myisam存儲(chǔ)引擎模式的索引類型。相對(duì)Hash索引,B+Tree在查找單條記錄的速度比不上Hash索引,但是因?yàn)楦m合排序等操作,所以它更受歡迎。畢竟不可能只對(duì)數(shù)據(jù)庫(kù)進(jìn)行單條記錄的操作。 帶順序訪問指針的B+Tree B+Tree所有索引數(shù)據(jù)都在葉子節(jié)點(diǎn)上,并且增加了順序訪問指針,每個(gè)葉子節(jié)點(diǎn)都有指向相鄰葉子節(jié)點(diǎn)的指針。 這樣做是為了提高區(qū)間效率,例如查詢key為從18到49的所有數(shù)據(jù)記錄,當(dāng)找到18后,只要順著節(jié)點(diǎn)和指針順序遍歷就可以以此向訪問到所有數(shù)據(jù)節(jié)點(diǎn),極大提高了區(qū)間查詢效率。 大大減少磁盤I/O讀取 數(shù)據(jù)庫(kù)系統(tǒng)的設(shè)計(jì)者巧妙利用了磁盤預(yù)讀原理,將一個(gè)節(jié)點(diǎn)的大小設(shè)為等于一個(gè)頁,這樣每個(gè)節(jié)點(diǎn)需要一次I/O就可以完全載入。
什么是索引索引(Index)是幫助數(shù)據(jù)庫(kù)高效獲取數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)。索引是在基于數(shù)據(jù)庫(kù)表創(chuàng)建的,它包含一個(gè)表中某些列的值以及記錄對(duì)應(yīng)的地址,并且把這些值存儲(chǔ)在一個(gè)數(shù)據(jù)結(jié)構(gòu)中。最常見的就是使用哈希表、B+樹作為索引。 一般的應(yīng)用系統(tǒng),讀寫比例在10:1左右,而且插入操作和一般的更新操作很少出現(xiàn)性能問題,在生產(chǎn)環(huán)境中,我們遇到最多的,也是最容易出問題的,還是一些復(fù)雜的查詢操作,因此對(duì)查詢語句的優(yōu)化顯然是重中之重。說起加速查詢,就不得不提到索引了。
為什么要使用索引我們知道,數(shù)據(jù)庫(kù)查詢是數(shù)據(jù)庫(kù)最主要的功能之一。而查詢速度當(dāng)然是越快越好。而當(dāng)數(shù)據(jù)量越來越大的時(shí)候,查詢花費(fèi)的時(shí)間會(huì)隨之增長(zhǎng)。而索引,可以加速數(shù)據(jù)的查詢。因?yàn)樗饕怯行蚺帕械摹?/p> 舉個(gè)例子來說,假設(shè)我們有一個(gè)數(shù)據(jù)庫(kù)表Employee,這個(gè)表分別有三個(gè)字段:name,age,address。假設(shè)表中有1000條記錄。 假如沒有使用索引,當(dāng)我們查詢名為“Jesus”的雇員的時(shí)候,即調(diào)用: select name,age,address from Employee where name = 'Jesus'; 此時(shí)數(shù)據(jù)庫(kù)不得不在Employee表中對(duì)這1000條記錄一條一條的進(jìn)行判斷name字段是否為“Jesus”。這也就是所謂的全表掃描。 而當(dāng)我們?cè)贓mployee表上的name字段上創(chuàng)建索引時(shí),當(dāng)我們查詢名為“Jesus”的雇員時(shí),會(huì)通過索引查找去查詢名為“Jesus”的雇員,因?yàn)樵撍饕呀?jīng)按照字母順序排列,因此要查找名為“Jesus”的記錄時(shí)會(huì)快很多,因?yàn)槊质鬃帜笧椤癑”的雇員都是排列在一起的。通過該索引,能獲取到表中對(duì)應(yīng)的記錄。 舉例說明使用索引的好處假設(shè)索引(索引是一種數(shù)據(jù)結(jié)構(gòu))是鏈表結(jié)構(gòu)。每個(gè)節(jié)點(diǎn)存儲(chǔ)的是關(guān)鍵字字段(這個(gè)例子中對(duì)應(yīng)的是name屬性)以及該關(guān)鍵字字段在數(shù)據(jù)庫(kù)表的對(duì)應(yīng)的記錄的地址。而這些節(jié)點(diǎn)是根據(jù)name屬性排序的(即根據(jù)字母順序排序)。因此,當(dāng)我們執(zhí)行上面說的查找名為“Jesus”的sql語句時(shí),數(shù)據(jù)庫(kù)會(huì)通過該索引來查詢,因?yàn)樵撴湵硎怯行蚺帕械?,在我們找到第一個(gè)name屬性為“Jesus”的節(jié)點(diǎn)后,繼續(xù)往后找,當(dāng)遇到name屬性不為“Jesus”的節(jié)點(diǎn)時(shí),就無需再往后查找了,因?yàn)楣?jié)點(diǎn)是根據(jù)name屬性有序排列的啊。假設(shè)第一個(gè)name=“Jesus”的節(jié)點(diǎn)是第499個(gè)節(jié)點(diǎn),最后一個(gè)name=“Jesus”的節(jié)點(diǎn)是第500個(gè)節(jié)點(diǎn),那么只需要遍歷501個(gè)節(jié)點(diǎn)就可以了。當(dāng)發(fā)現(xiàn)第501個(gè)節(jié)點(diǎn)的name字段不為“Jesus”,后面的499個(gè)節(jié)點(diǎn)也就無需遍歷了。通過索引,我們就找到了name為“Jesus”的節(jié)點(diǎn),而通過該節(jié)點(diǎn)的另一個(gè)屬性(關(guān)鍵字字段在數(shù)據(jù)庫(kù)表的對(duì)應(yīng)的記錄的地址),我們就能獲取到Employee表中滿足條件name=“Jesus”的記錄了。 通過使用索引,查詢判斷的次數(shù)就從1000次縮小到了501次了。起到了加速了查詢效率。但實(shí)際上數(shù)據(jù)庫(kù)中索引的結(jié)構(gòu),并不是鏈表結(jié)構(gòu)。 數(shù)據(jù)庫(kù)中使用什么數(shù)據(jù)結(jié)構(gòu)作為索引數(shù)據(jù)庫(kù)中實(shí)際使用的索引并不會(huì)是鏈表結(jié)構(gòu),因?yàn)樾侍土恕?nbsp; 另外,在選擇數(shù)據(jù)庫(kù)索引的結(jié)構(gòu)的時(shí)候,要考慮到另一個(gè)問題。索引是存在于磁盤中,當(dāng)索引非常大的時(shí)候,達(dá)到幾個(gè)G的時(shí)候,無法一次加載到內(nèi)存中。 考慮到上面兩個(gè)因素,數(shù)據(jù)庫(kù)中索引使用的是樹形結(jié)構(gòu)。 各種樹的名字有這么幾種樹: B-Tree B+-Tree B*-Tree 首先要明白三種樹名中的“-”起到的是分隔的作用,并不是“減”的意思。 因此正確的翻譯應(yīng)該是 為什么要強(qiáng)調(diào)上面這一點(diǎn)呢,因?yàn)橛械牟┪闹袑懙氖牵築樹是二叉樹,B-樹是多路搜索樹。 然而B樹和B-樹都是指B-Tree。引用維基百科上的話: B-tree Not to be confused with Binary tree.
也就是說,B-Tree并不是Binart tree。B-Tree的中文名是平衡多路搜索樹。 平衡二叉樹樹形結(jié)構(gòu)是計(jì)算機(jī)系統(tǒng)里最重要的數(shù)據(jù)結(jié)構(gòu)。 我們知道,二叉樹的查找的時(shí)間復(fù)雜度是O(log2N),其查找效率與深度有關(guān),而普通的二叉樹可能由于內(nèi)部節(jié)點(diǎn)排列問題退化成鏈表,這樣查找效率就會(huì)很低。因此平衡二叉樹是更好的選擇,因?yàn)樗3制胶?,即通過旋轉(zhuǎn)調(diào)整結(jié)構(gòu)保持最小的深度。其查找的時(shí)間復(fù)雜度也是O(log2N)。 但實(shí)際上,數(shù)據(jù)庫(kù)中索引的結(jié)構(gòu)也并非AVL樹或更優(yōu)秀的紅黑樹,盡管它的查詢的時(shí)間復(fù)雜度很低。 為什么平衡二叉樹也不適合作為索引之前說了平衡樹的查找時(shí)間復(fù)雜度是O(log2N),已經(jīng)很不錯(cuò)了,但還是不適合作為索引結(jié)構(gòu)。那么肯定是有一種更適合作為索引的數(shù)據(jù)結(jié)構(gòu)。那么這個(gè)更適合作為索引的數(shù)據(jù)結(jié)構(gòu),難道是查找的時(shí)間復(fù)雜度更低嗎?并不是。這種作為索引的數(shù)據(jù)結(jié)構(gòu)的查找的時(shí)間復(fù)雜度也近似O(log2N)。 那為什么平衡二叉樹不適合作為索引呢? 索引是存在于索引文件中,是存在于磁盤中的。因?yàn)樗饕ǔJ呛艽蟮?,因此無法一次將全部索引加載到內(nèi)存當(dāng)中,因此每次只能從磁盤中讀取一個(gè)磁盤頁的數(shù)據(jù)到內(nèi)存中。而這個(gè)磁盤的讀取的速度較內(nèi)存中的讀取速度而言是差了好幾個(gè)級(jí)別。 注意,我們說的平衡二叉樹結(jié)構(gòu),指的是邏輯結(jié)構(gòu)上的平衡二叉樹,其物理實(shí)現(xiàn)是數(shù)組。然后由于在邏輯結(jié)構(gòu)上相近的節(jié)點(diǎn)在物理結(jié)構(gòu)上可能會(huì)差很遠(yuǎn)。因此,每次讀取的磁盤頁的數(shù)據(jù)中有許多是用不上的。因此,查找過程中要進(jìn)行許多次的磁盤讀取操作。 而適合作為索引的結(jié)構(gòu)應(yīng)該是盡可能少的執(zhí)行磁盤IO操作,因?yàn)閳?zhí)行磁盤IO操作非常的耗時(shí)。因此,平衡二叉樹并不適合作為索引結(jié)構(gòu)。 B-Tree適合作為索引平衡二叉樹不適合作為索引。那么什么才適合作為索引——B樹。 平衡二叉樹沒能充分利用磁盤預(yù)讀功能,而B樹是為了充分利用磁盤預(yù)讀功能來而創(chuàng)建的一種數(shù)據(jù)結(jié)構(gòu),也就是說B樹就是為了作為索引才被發(fā)明出來的的。 來看看關(guān)于“局部性原理與磁盤預(yù)讀”的知識(shí): 局部性原理與磁盤預(yù)讀: 由于存儲(chǔ)介質(zhì)的特性,磁盤本身存取就比主存慢很多,再加上機(jī)械運(yùn)動(dòng)耗費(fèi),磁盤的存取速度往往是主存的幾百分分之一,因此為了提高效率,要盡量減少磁盤I/O。為了達(dá)到這個(gè)目的,磁盤往往不是嚴(yán)格按需讀取,而是每次都會(huì)預(yù)讀,即使只需要一個(gè)字節(jié),磁盤也會(huì)從這個(gè)位置開始,順序向后讀取一定長(zhǎng)度的數(shù)據(jù)放入內(nèi)存。這樣做的理論依據(jù)是計(jì)算機(jī)科學(xué)中著名的局部性原理: 當(dāng)一個(gè)數(shù)據(jù)被用到時(shí),其附近的數(shù)據(jù)也通常會(huì)馬上被使用。 程序運(yùn)行期間所需要的數(shù)據(jù)通常比較集中。 由于磁盤順序讀取的效率很高(不需要尋道時(shí)間,只需很少的旋轉(zhuǎn)時(shí)間),因此對(duì)于具有局部性的程序來說,預(yù)讀可以提高I/O效率。
搞清楚上面的意思。磁盤預(yù)讀是具體實(shí)現(xiàn),其理論依據(jù)是局部性原理。 為什么說紅黑樹沒能充分利用磁盤預(yù)讀功能,引用一篇博文的一段話: 紅黑樹這種結(jié)構(gòu),h明顯要深的多。由于邏輯上很近的節(jié)點(diǎn)(父子)物理上可能很遠(yuǎn),無法利用局部性,所以紅黑樹的I/O漸進(jìn)復(fù)雜度也為O(h),效率明顯比B-Tree差很多。
也就是說,使用紅黑樹(平衡二叉樹)結(jié)構(gòu)的話,每次磁盤預(yù)讀中的很多數(shù)據(jù)是用不上的數(shù)據(jù)。因此,它沒能利用好磁盤預(yù)讀的提供的數(shù)據(jù)。然后又由于深度大(較B樹而言),所以進(jìn)行的磁盤IO操作更多。 B樹的每個(gè)節(jié)點(diǎn)可以存儲(chǔ)多個(gè)關(guān)鍵字,它將節(jié)點(diǎn)大小設(shè)置為磁盤頁的大小,充分利用了磁盤預(yù)讀的功能。每次讀取磁盤頁時(shí)就會(huì)讀取一整個(gè)節(jié)點(diǎn)。也正因每個(gè)節(jié)點(diǎn)存儲(chǔ)著非常多個(gè)關(guān)鍵字,樹的深度就會(huì)非常的小。進(jìn)而要執(zhí)行的磁盤讀取操作次數(shù)就會(huì)非常少,更多的是在內(nèi)存中對(duì)讀取進(jìn)來的數(shù)據(jù)進(jìn)行查找。 B樹的查詢,主要發(fā)生在內(nèi)存中,而平衡二叉樹的查詢,則是發(fā)生在磁盤讀取中。因此,雖然B樹查詢查詢的次數(shù)不比平衡二叉樹的次數(shù)少,但是相比起磁盤IO速度,內(nèi)存中比較的耗時(shí)就可以忽略不計(jì)了。因此,B樹更適合作為索引。 比B樹更適合作為索引的結(jié)構(gòu)——B+樹比B樹更適合作為索引的結(jié)構(gòu)是B+樹。MySQL中也是使用B+樹作為索引。它是B樹的變種,因此是基于B樹來改進(jìn)的。為什么B+樹會(huì)比B樹更加優(yōu)秀呢? B樹:有序數(shù)組+平衡多叉樹; B+樹的關(guān)鍵字全部存放在葉子節(jié)點(diǎn)中,非葉子節(jié)點(diǎn)用來做索引,而葉子節(jié)點(diǎn)中有一個(gè)指針指向一下個(gè)葉子節(jié)點(diǎn)。做這個(gè)優(yōu)化的目的是為了提高區(qū)間訪問的性能。而正是這個(gè)特性決定了B+樹更適合用來存儲(chǔ)外部數(shù)據(jù)。 引用一段話: 走進(jìn)搜索引擎的作者梁斌老師針對(duì)B樹、B+樹給出了他的意見(為了真實(shí)性,特引用其原話,未作任何改動(dòng)): “B+樹還有一個(gè)最大的好處,方便掃庫(kù),B樹必須用中序遍歷的方法按序掃庫(kù),而B+樹直接從葉子結(jié)點(diǎn)挨個(gè)掃一遍就完了,B+樹支持range-query非常方便,而B樹不支持。這是數(shù)據(jù)庫(kù)選用B+樹的最主要原因。 比如要查 5-10之間的,B+樹一把到5這個(gè)標(biāo)記,再一把到10,然后串起來就行了,B樹就非常麻煩。B樹的好處,就是成功查詢特別有利,因?yàn)闃涞母叨瓤傮w要比B+樹矮。不成功的情況下,B樹也比B+樹稍稍占一點(diǎn)點(diǎn)便宜。 B樹比如你的例子中查,17的話,一把就得到結(jié)果了, 有很多基于頻率的搜索是選用B樹,越頻繁query的結(jié)點(diǎn)越往根上走,前提是需要對(duì)query做統(tǒng)計(jì),而且要對(duì)key做一些變化。 另外B樹也好B+樹也好,根或者上面幾層因?yàn)楸环磸?fù)query,所以這幾塊基本都在內(nèi)存中,不會(huì)出現(xiàn)讀磁盤IO,一般已啟動(dòng)的時(shí)候,就會(huì)主動(dòng)換入內(nèi)存。”
舉個(gè)例子來對(duì)比。 比如說,我們要查找關(guān)鍵字范圍在3到7的關(guān)鍵字,在找到第一個(gè)符合條件的數(shù)字3后,訪問完第一個(gè)關(guān)鍵字所在的塊后,得遍歷這個(gè)B樹,獲取下一個(gè)塊,直到遇到一個(gè)不符合條件的關(guān)鍵字。遍歷的過程是比較復(fù)雜的。 B+樹(葉節(jié)點(diǎn)保存數(shù)據(jù),其他的節(jié)點(diǎn) 全部存放索引): 相比之下,B+樹的基于范圍的查詢簡(jiǎn)潔很多。由于葉子節(jié)點(diǎn)有指向下一個(gè)葉子節(jié)點(diǎn)的指針,因此從塊1到塊2的訪問,通過塊1指向塊2的指針即可。從塊2到塊3也是通過一個(gè)指針即可。 引用一篇博文中網(wǎng)友評(píng)論的一段話: 數(shù)據(jù)庫(kù)索引采用B+樹的主要原因是B樹在提高了磁盤IO性能的同時(shí)并沒有解決元素遍歷的效率低下的問題。正是為了解決這個(gè)問題,B+樹應(yīng)運(yùn)而生。 正如上面所說,在數(shù)據(jù)庫(kù)中基于范圍的查詢是非常頻繁的,因此MySQL最終選擇的索引結(jié)構(gòu)是B+樹而不是B樹。
二、索引的原理一 索引原理 索引的目的在于提高查詢效率,與我們查閱圖書所用的目錄是一個(gè)道理:先定位到章,然后定位到該章下的一個(gè)小節(jié),然后找到頁數(shù)。相似的例子還有:查字典,查火車車次,飛機(jī)航班等 本質(zhì)都是:通過不斷地縮小想要獲取數(shù)據(jù)的范圍來篩選出最終想要的結(jié)果,同時(shí)把隨機(jī)的事件變成順序的事件,也就是說,有了這種索引機(jī)制,我們可以總是用同一種查找方式來鎖定數(shù)據(jù)。 數(shù)據(jù)庫(kù)也是一樣,但顯然要復(fù)雜的多,因?yàn)椴粌H面臨著等值查詢,還有范圍查詢(>、<、between、in)、模糊查詢(like)、并集查詢(or)等等。數(shù)據(jù)庫(kù)應(yīng)該選擇怎么樣的方式來應(yīng)對(duì)所有的問題呢?我們回想字典的例子,能不能把數(shù)據(jù)分成段,然后分段查詢呢?最簡(jiǎn)單的如果1000條數(shù)據(jù),1到100分成第一段,101到200分成第二段,201到300分成第三段......這樣查第250條數(shù)據(jù),只要找第三段就可以了,一下子去除了90%的無效數(shù)據(jù)。但如果是1千萬的記錄呢,分成幾段比較好?稍有算法基礎(chǔ)的同學(xué)會(huì)想到搜索樹,其平均復(fù)雜度是lgN,具有不錯(cuò)的查詢性能。但這里我們忽略了一個(gè)關(guān)鍵的問題,復(fù)雜度模型是基于每次相同的操作成本來考慮的。而數(shù)據(jù)庫(kù)實(shí)現(xiàn)比較復(fù)雜,一方面數(shù)據(jù)是保存在磁盤上的,另外一方面為了提高性能,每次又可以把部分?jǐn)?shù)據(jù)讀入內(nèi)存來計(jì)算,因?yàn)槲覀冎涝L問磁盤的成本大概是訪問內(nèi)存的十萬倍左右,所以簡(jiǎn)單的搜索樹難以滿足復(fù)雜的應(yīng)用場(chǎng)景。 二 磁盤IO與預(yù)讀 考慮到磁盤IO是非常高昂的操作,計(jì)算機(jī)操作系統(tǒng)做了一些優(yōu)化,當(dāng)一次IO時(shí),不光把當(dāng)前磁盤地址的數(shù)據(jù),而是把相鄰的數(shù)據(jù)也都讀取到內(nèi)存緩沖區(qū)內(nèi),因?yàn)榫植款A(yù)讀性原理告訴我們,當(dāng)計(jì)算機(jī)訪問一個(gè)地址的數(shù)據(jù)的時(shí)候,與其相鄰的數(shù)據(jù)也會(huì)很快被訪問到。每一次IO讀取的數(shù)據(jù)我們稱之為一頁(page)。具體一頁有多大數(shù)據(jù)跟操作系統(tǒng)有關(guān),一般為4k或8k,也就是我們讀取一頁內(nèi)的數(shù)據(jù)時(shí)候,實(shí)際上才發(fā)生了一次IO,這個(gè)理論對(duì)于索引的數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)非常有幫助。 三、索引的數(shù)據(jù)結(jié)構(gòu) 任何一種數(shù)據(jù)結(jié)構(gòu)都不是憑空產(chǎn)生的,一定會(huì)有它的背景和使用場(chǎng)景,我們現(xiàn)在總結(jié)一下,我們需要這種數(shù)據(jù)結(jié)構(gòu)能夠做些什么,其實(shí)很簡(jiǎn)單,那就是:每次查找數(shù)據(jù)時(shí)把磁盤IO次數(shù)控制在一個(gè)很小的數(shù)量級(jí),最好是常數(shù)數(shù)量級(jí)。那么我們就想到如果一個(gè)高度可控的多路搜索樹是否能滿足需求呢?就這樣,b+樹應(yīng)運(yùn)而生。 如上圖,是一顆b+樹,關(guān)于b+樹的定義可以參見B+樹,這里只說一些重點(diǎn),淺藍(lán)色的塊我們稱之為一個(gè)磁盤塊,可以看到每個(gè)磁盤塊包含幾個(gè)數(shù)據(jù)項(xiàng)(深藍(lán)色所示)和指針(黃色所示),如磁盤塊1包含數(shù)據(jù)項(xiàng)17和35,包含指針P1、P2、P3,P1表示小于17的磁盤塊,P2表示在17和35之間的磁盤塊,P3表示大于35的磁盤塊。真實(shí)的數(shù)據(jù)存在于葉子節(jié)點(diǎn)即3、5、9、10、13、15、28、29、36、60、75、79、90、99。非葉子節(jié)點(diǎn)只不存儲(chǔ)真實(shí)的數(shù)據(jù),只存儲(chǔ)指引搜索方向的數(shù)據(jù)項(xiàng),如17、35并不真實(shí)存在于數(shù)據(jù)表中。 ###b+樹的查找過程 ###b+樹性質(zhì) 這也是經(jīng)常考察的,比如 我定義了 A,B,C的聯(lián)合索引,如果 我只傳遞了 A,B 能走索引嗎?答案是能,因?yàn)樽钭髠?cè)原理(百度問過) 補(bǔ)充一下. 全文索引(FULLTEXT)=mysql的 myISAM搜索引擎默認(rèn)的索引類型 MySQL從3.23.23版開始支持全文索引和全文檢索,fulltext索引僅可用于 MyISAM 表;他們可以從CHAR、VARCHAR或TEXT列中作為CREATE TABLE語句的一部分被創(chuàng)建,或是隨后使用ALTER TABLE 或CREATE INDEX被添加。////對(duì)于較大的數(shù)據(jù)集,將你的資料輸入一個(gè)沒有FULLTEXT索引的表中,然后創(chuàng)建索引,其速度比把資料輸入現(xiàn)有FULLTEXT索引的速度更為快。不過切記對(duì)于大容量的數(shù)據(jù)表,生成全文索引是一個(gè)非常消耗時(shí)間非常消耗硬盤空間的做法。 參考:Mysql索引詳解及優(yōu)化(key和index區(qū)別) 四,索引使用注意事項(xiàng)1,不要濫用索引 ①,索引提高查詢速度,卻會(huì)降低更新表的速度,因?yàn)楦卤頃r(shí),mysql不僅要更新數(shù)據(jù),保存數(shù)據(jù),還要更新索引,保存索引 ②,索引會(huì)占用磁盤空間 2,索引不會(huì)包含含有NULL值的列 復(fù)合索引只要有一列含有NULL值,那么這一列對(duì)于此符合索引就是無效的,因此我們?cè)谠O(shè)計(jì)數(shù)據(jù)庫(kù)設(shè)計(jì)時(shí)不要讓字段的默認(rèn)值為NULL。 3,MySQL查詢只是用一個(gè)索引 如果where字句中使用了索引的話,那么order by中的列是不會(huì)使用索引的 4,like like '%aaa%'不會(huì)使用索引而like "aaa%"可以使用索引
|
|