1. 程式人生 > >MySQL---什麼是索引,作用?原理?MySQL的原理?

MySQL---什麼是索引,作用?原理?MySQL的原理?

索引的定義

索引是一個單獨的、物理的資料庫結構,它是某個表中一列或若干列值的集合和相應的指向表中物理標識這些值的資料頁的邏輯指標清單。索引提供指向儲存在表的指定列中的資料值的指標,然後根據您指定的排序順序對這些指標排序。

索引的作用

建立索引的優點:

1.大大加快資料的檢索速度;

2.建立唯一性索引,保證資料庫表中每一行資料的唯一性;

3.加速表和表之間的連線;

4.在使用分組和排序子句進行資料檢索時,可以顯著減少查詢中分組和排序的時間。

5.通過使用索引,可以在查詢的過程中,使用優化隱藏器,提高系統的效能。 

索引的原理

MySQL支援諸多儲存引擎,而各種儲存引擎對索引的支援也各不相同,因此MySQL資料庫支援多種索引型別,如BTree索引,B+Tree索引,雜湊索引,全文索引

等等

1、雜湊索引:

只有memory(記憶體)儲存引擎支援雜湊索引,雜湊索引用索引列的值計算該值的hashCode,然後在hashCode相應的位置存執該值所在行資料的物理位置,因為使用雜湊演算法,因此訪問速度非常快,但是一個值只能對應一個hashCode,而且是雜湊的分佈方式,因此雜湊索引不支援範圍查詢和排序的功能。

2、全文索引:

FULLTEXT(全文)索引,僅可用於MyISAM和InnoDB,針對較大的資料,生成全文索引非常的消耗時間和空間。對於文字的大物件,或者較大的CHAR型別的資料,如果使用普通索引,那麼匹配文字前幾個字元還是可行的,但是想要匹配文字中間的幾個單詞,那麼就要使用LIKE %word%來匹配,這樣需要很長的時間來處理,響應時間會大大增加,這種情況,就可使用時FULLTEXT索引了,在生成FULLTEXT索引時,會為文字生成一份單詞的清單,在索引時及根據這個單詞的清單來索引。FULLTEXT可以在建立表的時候建立,也可以在需要的時候用ALTER或者CREATE INDEX來新增:

  1. //建立表的時候新增FULLTEXT索引

  2. CTREATE TABLE my_table(

  3. id INT(10) PRIMARY KEY,

  4. name VARCHAR(10) NOT NULL,

  5. my_text text CHARACTER SET utf8 COLLATE utf8_general_ci NULL,

  6. FULLTEXT(my_text));

  1. //建立表以後,在需要的時候新增FULLTEXT索引

  2. ALTER my_table ADD FULLTEXT ft_index(my_text);

  3. CREATE INDEX ft_index ON my_table(my_text);

*對於較大的資料集,把資料新增到一個沒有FULLTEXT索引的表,然後新增FULLTEXT索引的速度比把資料新增到一個已經有FULLTEXT索引的錶快。

*MySQL自帶的全文索引只能用於MyISAM儲存引擎,如果是其它資料引擎,那麼全文索引不會生效。

*在MySQL中,全文索引支隊英文有用,目前對中文還不支援。

*在MySQL中,如果檢索的字串太短則無法檢索得到預期的結果,檢索的字串長度至少為4位元組,此外,如果檢索的字元包括停止詞,那麼停止詞會被忽略。

3、BTree索引和B+Tree索引

  • BTree索引

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

每個葉子結點的高度一樣,等於h;

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

葉子結點指標都為null;

非葉子結點的key都是[key,data]二元組,其中key表示作為索引的鍵,data為鍵值所在行的資料;

BTree的結構如下:

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

  • B+Tree索引

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

B+Tree中的非葉子結點不儲存資料,只儲存鍵值;

B+Tree的葉子結點沒有指標,所有鍵值都會出現在葉子結點上,且key儲存的鍵值對應的資料的實體地址;

B+Tree的結構如下:

一般來說B+Tree比BTree更適合實現外存的索引結構,因為儲存引擎的設計專家巧妙的利用了外存(磁碟)的儲存結構,即磁碟的一個扇區是整數倍的page(頁),頁是儲存中的一個單位,通常預設為4K,因此索引結構的節點被設計為一個頁的大小,然後利用外存的“預讀取”原則,每次讀取的時候,把整個節點的資料讀取到記憶體中,然後在記憶體中查詢,已知記憶體的讀取速度是外存讀取I/O速度的幾百倍,那麼提升查詢速度的關鍵就在於儘可能少的磁碟I/O,那麼可以知道,每個節點中的key個數越多,那麼樹的高度越小,需要I/O的次數越少,因此一般來說B+Tree比BTree更快,因為B+Tree的非葉節點中不儲存data,就可以儲存更多的key

  • 帶順序索引的B+TREE

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

B+Tree的結構如下:

分析了MySQL的索引結構的實現原理,然後我們來看看具體的儲存引擎怎麼實現索引結構的,MySQL中最常見的兩種儲存引擎分別是MyISAM和InnoDB,分別實現了非聚簇索引和聚簇索引。

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

MyISAM——聚簇索引

  • MyISAM儲存引擎採用的是非聚簇索引,非聚簇索引的主索引和輔助索引幾乎是一樣的,只是主索引不允許重複,不允許空值,他們的葉子結點的key都儲存指向鍵值對應的資料的實體地址
  • 非聚簇索引的資料表和索引表是分開儲存的。
  • 非聚簇索引中的資料是根據資料的插入順序儲存。因此非聚簇索引更適合單個數據的查詢。插入順序不受鍵值影響。
  • 只有在MyISAM中才能使用FULLTEXT索引。

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

InnoDB——聚簇索引

  • 聚簇索引的主索引的葉子結點儲存的是鍵值對應的資料本身,輔助索引的葉子結點儲存的是鍵值對應的資料的主鍵鍵值。因此主鍵的值長度越小越好,型別越簡單越好。
  • 聚簇索引的資料和主鍵索引儲存在一起。
  • 聚簇索引的資料是根據主鍵的順序儲存。因此適合按主鍵索引的區間查詢,可以有更少的磁碟I/O,加快查詢速度。但是也是因為這個原因,聚簇索引的插入順序最好按照主鍵單調的順序插入,否則會頻繁的引起頁分裂,嚴重影響效能。
  • 在InnoDB中,如果只需要查詢索引的列,就儘量不要加入其它的列,這樣會提高查詢效率。

*使用主索引的時候,更適合使用聚簇索引,因為聚簇索引只需要查詢一次,而非聚簇索引在查到資料的地址後,還要進行一次I/O查詢資料。

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

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

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