tft每日頭條

 > 科技

 > mysql組合索引和普通索引

mysql組合索引和普通索引

科技 更新时间:2024-08-08 11:26:42
概述

MySQL支持諸多存儲引擎,而各種存儲引擎對索引的支持也各不相同,因此MySQL數據庫支持多種索引類型,如BTree索引,B Tree索引,哈希索引,全文索引等等。下面對這幾個索引的實現原理做個簡單介紹。


01哈希索引

mysql組合索引和普通索引(詳解mysql數據庫索引的實現原理--BTree索引)1

隻有memory(内存)存儲引擎支持哈希索引,哈希索引用索引列的值計算該值的hashCode,然後在hashCode相應的位置存執該值所在行數據的物理位置,因為使用散列算法,因此訪問速度非常快,但是一個值隻能對應一個hashCode,而且是散列的分布方式,因此哈希索引不支持範圍查找和排序的功能。

簡單地說,哈希索引就是采用一定的哈希算法,把鍵值換算成新的哈希值,檢索時不需要類似B 樹那樣從根節點到葉子節點逐級查找,隻需一次哈希算法即可立刻定位到相應的位置,速度非常快。


02全文索引

FULLTEXT(全文)索引,僅可用于MyISAM和InnoDB,針對較大的數據,生成全文索引非常的消耗時間和空間。對于文本的大對象,或者較大的CHAR類型的數據,如果使用普通索引,那麼匹配文本前幾個字符還是可行的,但是想要匹配文本中間的幾個單詞,那麼就要使用LIKE %word%來匹配,這樣需要很長的時間來處理,響應時間會大大增加,這種情況,就可使用時FULLTEXT索引了,在生成FULLTEXT索引時,會為文本生成一份單詞的清單,在索引時及根據這個單詞的清單來索引

mysql組合索引和普通索引(詳解mysql數據庫索引的實現原理--BTree索引)2

sphinx--全文索引

FULLTEXT可以在創建表的時候創建,也可以在需要的時候用ALTER或者CREATE INDEX來添加:

//創建表的時候添加FULLTEXT索引 CTREATE TABLE my_table( id INT(10) PRIMARY KEY, name VARCHAR(10) NOT NULL, my_text TEXT, FULLTEXT(my_text) )ENGINE=MyISAM DEFAULT CHARSET=utf8; //創建表以後,在需要的時候添加FULLTEXT索引 ALTER TABLE my_table ADD FULLTEXT INDEX ft_index(column_name);

全文索引的查詢也有自己特殊的語法,而不能使用LIKE %查詢字符串%的模糊查詢語法

SELECT * FROM table_name MATCH(ft_index) AGAINST('查詢字符串');

注意:

  • *對于較大的數據集,把數據添加到一個沒有FULLTEXT索引的表,然後添加FULLTEXT索引的速度比把數據添加到一個已經有FULLTEXT索引的表快。
  • *5.6版本前的MySQL自帶的全文索引隻能用于MyISAM存儲引擎,如果是其它數據引擎,那麼全文索引不會生效。5.6版本之後InnoDB存儲引擎開始支持全文索引
  • *在MySQL中,全文索引支隊英文有用,目前對中文還不支持。5.7版本之後通過使用ngram插件開始支持中文。
  • *在MySQL中,如果檢索的字符串太短則無法檢索得到預期的結果,檢索的字符串長度至少為4字節,此外,如果檢索的字符包括停止詞,那麼停止詞會被忽略。

03BTree索引和B Tree索引

1、BTree索引

BTree是平衡搜索多叉樹,設樹的度為2d(d>1),高度為h,那麼BTree要滿足以一下條件:

  • 每個葉子結點的高度一樣,等于h;
  • 每個非葉子結點由n-1個key和n個指針point組成,其中d<=n<=2d,key和point相互間隔,結點兩端一定是key;
  • 葉子結點指針都為null;
  • 非葉子結點的key都是[key,data]二元組,其中key表示作為索引的鍵,data為鍵值所在行的數據;

BTree的結構如下:

mysql組合索引和普通索引(詳解mysql數據庫索引的實現原理--BTree索引)3

在BTree的機構下,就可以使用二分查找的查找方式,查找複雜度為h*log(n),一般來說樹的高度是很小的,一般為3左右,因此BTree是一個非常高效的查找結構。

2、B Tree索引

B Tree是BTree的一個變種,設d為樹的度數,h為樹的高度,B Tree和BTree的不同主要在于:

B Tree中的非葉子結點不存儲數據,隻存儲鍵值;

B Tree的葉子結點沒有指針,所有鍵值都會出現在葉子結點上,且key存儲的鍵值對應data數據的物理地址;

B Tree的每個非葉子節點由n個鍵值key和n個指針point組成;

B Tree的結構如下:

mysql組合索引和普通索引(詳解mysql數據庫索引的實現原理--BTree索引)4

3、B Tree對比BTree的優點

1)、磁盤讀寫代價更低

一般來說B Tree比BTree更适合實現外存的索引結構,因為存儲引擎的設計專家巧妙的利用了外存(磁盤)的存儲結構,即磁盤的最小存儲單位是扇區(sector),而操作系統的塊(block)通常是整數倍的sector,操作系統以頁(page)為單位管理内存,一頁(page)通常默認為4K,數據庫的頁通常設置為操作系統頁的整數倍,因此索引結構的節點被設計為一個頁的大小,然後利用外存的“預讀取”原則,每次讀取的時候,把整個節點的數據讀取到内存中,然後在内存中查找,已知内存的讀取速度是外存讀取I/O速度的幾百倍,那麼提升查找速度的關鍵就在于盡可能少的磁盤I/O,那麼可以知道,每個節點中的key個數越多,那麼樹的高度越小,需要I/O的次數越少,因此一般來說B Tree比BTree更快,因為B Tree的非葉節點中不存儲data,就可以存儲更多的key。

2)、查詢速度更穩定

由于B Tree非葉子節點不存儲數據(data),因此所有的數據都要查詢至葉子節點,而葉子節點的高度都是相同的,因此所有數據的查詢速度都是一樣的。

4、帶順序索引的B TREE

很多存儲引擎在B Tree的基礎上進行了優化,添加了指向相鄰葉節點的指針,形成了帶有順序訪問指針的B Tree,這樣做是為了提高區間查找的效率,隻要找到第一個值那麼就可以順序的查找後面的值。

B Tree的結構如下:

mysql組合索引和普通索引(詳解mysql數據庫索引的實現原理--BTree索引)5


04聚簇索引和非聚簇索引

上面主要說的是MySQL的索引結構的實現原理,接下來看看具體的存儲引擎怎麼實現索引結構的,MySQL中最常見的兩種存儲引擎分别是MyISAM和InnoDB,分别實現了非聚簇索引和聚簇索引。

聚簇索引的解釋是:聚簇索引的順序就是數據的物理存儲順序

非聚簇索引的解釋是:索引順序與數據物理排列順序無關

首先要介紹幾個概念,在索引的分類中,我們可以按照索引的鍵是否為主鍵來分為“主索引”和“輔助索引”,使用主鍵鍵值建立的索引稱為“主索引”,其它的稱為“輔助索引”。因此主索引隻能有一個,輔助索引可以有很多個。

1、MyISAM——非聚簇索引

MyISAM存儲引擎采用的是非聚簇索引,非聚簇索引的主索引和輔助索引幾乎是一樣的,隻是主索引不允許重複,不允許空值,他們的葉子結點的key都存儲指向鍵值對應的數據的物理地址。

mysql組合索引和普通索引(詳解mysql數據庫索引的實現原理--BTree索引)6

myisam(非聚簇)表分布

非聚簇索引的數據表和索引表是分開存儲的。

非聚簇索引中的數據是根據數據的插入順序保存。因此非聚簇索引更适合單個數據的查詢。插入順序不受鍵值影響。

隻有在MyISAM中才能使用FULLTEXT索引。(mysql5.6以後innoDB也支持全文索引)

*最開始我一直不懂既然非聚簇索引的主索引和輔助索引指向相同的内容,為什麼還要輔助索引這個東西呢,後來才明白索引不就是用來查詢的嗎,用在那些地方呢,不就是WHERE和ORDER BY 語句後面嗎,那麼如果查詢的條件不是主鍵怎麼辦呢,這個時候就需要輔助索引了。

2、InnoDB——聚簇索引

聚簇索引的主索引的葉子結點存儲的是鍵值對應的數據本身,輔助索引的葉子結點存儲的是鍵值對應的數據的主鍵鍵值。因此主鍵的值長度越小越好,類型越簡單越好。

mysql組合索引和普通索引(詳解mysql數據庫索引的實現原理--BTree索引)7

InnoDB(聚簇)表分布

聚簇索引的數據和主鍵索引存儲在一起。

聚簇索引的數據是根據主鍵的順序保存。因此适合按主鍵索引的區間查找,可以有更少的磁盤I/O,加快查詢速度。但是也是因為這個原因,聚簇索引的插入順序最好按照主鍵單調的順序插入,否則會頻繁的引起頁分裂,嚴重影響性能。

在InnoDB中,如果隻需要查找索引的列,就盡量不要加入其它的列,這樣會提高查詢效率。

*使用主索引的時候,更适合使用聚簇索引,因為聚簇索引隻需要查找一次,而非聚簇索引在查到數據的地址後,還要進行一次I/O查找數據。

*因為聚簇輔助索引存儲的是主鍵的鍵值,因此可以在數據行移動或者頁分裂的時候降低成本,因為這時不用維護輔助索引。但是由于主索引存儲的是數據本身,因此聚簇索引會占用更多的空間。

*聚簇索引在插入新數據的時候比非聚簇索引慢很多,因為插入新數據時需要檢測主鍵是否重複,這需要遍曆主索引的所有葉節點,而非聚簇索引的葉節點保存的是數據地址,占用空間少,因此分布集中,查詢的時候I/O更少,但聚簇索引的主索引中存儲的是數據本身,數據占用空間大,分布範圍更大,可能占用好多的扇區,因此需要更多次I/O才能遍曆完畢。

3、聚簇索引和非聚簇索引的區别

下圖可以形象的說明聚簇索引和非聚簇索引的區别:

mysql組合索引和普通索引(詳解mysql數據庫索引的實現原理--BTree索引)8

從上圖中可以看到聚簇索引的輔助索引的葉子節點的data存儲的是主鍵的值,主索引的葉子節點的data存儲的是數據本身,也就是說數據和索引存儲在一起,并且索引查詢到的地方就是數據(data)本身,那麼索引的順序和數據本身的順序就是相同的;

而非聚簇索引的主索引和輔助索引的葉子節點的data都是存儲的數據的物理地址,也就是說索引和數據并不是存儲在一起的,數據的順序和索引的順序并沒有任何關系,也就是索引順序與數據物理排列順序無關。

ps:MyISAM和innoDB的區别總結如下:

mysql組合索引和普通索引(詳解mysql數據庫索引的實現原理--BTree索引)9


總結

InnoDB 支持事務,支持行級别鎖定,支持 B-tree、Full-text 等索引,不支持 Hash 索引;

MyISAM 不支持事務,支持表級别鎖定,支持 B-tree、Full-text 等索引,不支持 Hash 索引;

此外,Memory 不支持事務,支持表級别鎖定,支持 B-tree、Hash 等索引,不支持 Full-text 索引;

後面會分享更多devops和DBA方面的内容,感興趣的朋友可以關注一下~

mysql組合索引和普通索引(詳解mysql數據庫索引的實現原理--BTree索引)10

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关科技资讯推荐

热门科技资讯推荐

网友关注

Copyright 2023-2024 - www.tftnews.com All Rights Reserved