MySQL索引型別與優化

2021-09-30 19:51:22 字數 2594 閱讀 6530

索引優化

參考資料

在mysql中,索引是在儲存引擎層而不是伺服器層實現的,所以不同的儲存引擎的索引型別和實現不同。

大多數儲存引擎都使用b-tree作為預設索引型別,但實際在技術上往往使用的是b+tree,例如innodb。b-tree索引之能夠加快訪問資料的速度,是因為儲存引擎不再需要進行全表掃瞄來獲取需要的資料,取而代之的是從索引的根節點開始進行搜尋。關於b-treeb+tree的工作原理可以參考之前的一篇筆記:常用查詢演算法之b/b+樹。

b-tree索引適用於全鍵值、鍵值範圍或鍵字首(最左字首)查詢。因為索引樹中的節點是有序的,所以除了按值查詢之外,索引還可以用於查詢中的order by操作。

b-tree同樣也有一些限制:

雜湊索引基於雜湊表實現,對於每一行資料,儲存引擎都會對所有索引列計算乙個雜湊碼並儲存在索引中,同時在雜湊表中儲存指向每個資料行的指標。如果多個列的雜湊值相同,索引會以鍊錶的方式存放多個記錄指標到同乙個雜湊條目中。雜湊索引有如下限制:

innodb引擎有乙個特殊的功能叫做「自適應雜湊索引」,當innodb注意到某些索引值被使用得非常頻繁時,它會在記憶體中基於b-tree索引之上再建立乙個雜湊索引,這樣就讓b+tree索引具有雜湊索引的一些優點,比如快速的雜湊查詢。

myisam儲存引擎支援空間資料索引(r-tree),可以用作地理資料儲存。空間索引會從所有維度來索引資料,查詢時可以有效利用任意維度來組合查詢。必須使用mysql的gis相關函式來維護資料。

在進行查詢時,索引列不能是表示式的一部分,也不能是函式的引數,否則mysql無法使用索引。

例如:select actor_id from sakila.actor where actor_id + 1 = 5;

在需要使用多個列作為條件進行查詢時,使用多列索引比使用多個單列索引效能更好。例如下面的語句中,最好把actor_idfilm_id設定為多列索引:

select film_id, actor_id from sakila.film_actor

where actor_id =

1and film_id =

1;

將選擇性最強的索引列放在前面。索引的選擇性是指不重複的索引值(基數)和記錄總數的比值,選擇性越高則查詢效率也越高,因為選擇性高的索引可以讓mysql在查詢時過濾掉更多的行。

對於很長的字串可以索引開始的部分字元,使得字首的選擇性接近於完整列的選擇性。

b-tree索引型別都可以用在myisam和innodb上,但innodb有聚簇索引的特性而myisam沒有。

聚簇表示資料行和相鄰的鍵值緊湊地儲存在一起,因為無法同時把資料行存放在兩個不同的地方,所以每張innodb引擎表都只有乙個聚簇索引。一般情況,聚簇索引就是主鍵索引(因為聚簇索引在有主鍵的情況下,預設指定主鍵為聚簇索引),而非聚簇索引都是二級索引。

如果沒有定義主鍵,innodb會選擇乙個唯一的非空索引代替。如果沒有這樣的索引,innodb會隱式定義乙個主鍵來作為聚簇索引。採用聚簇索引,索引和其他列值儲存在一起,因此資料訪問比採用非聚簇索引(如myisam引擎)更快,節省了磁碟i/o資源。

二級索引葉子節點儲存的不是指向行的物理位置的指標,而是行的主鍵值。通過二級索引查詢行,儲存引擎需要找到二級索引的葉子節點獲得對應的主鍵值,然後根據這個值去聚簇索引中查詢到對應的行。這樣雖然會讓二級索引占用更多的空間,但換來的好處是innodb在移動行時減少了二級索引的維護工作。

myisam沒有聚簇索引的特性,主鍵索引和其它索引在結構上沒有什麼不同。

使用innodb儲存引擎時應該盡可能地按主鍵順序插入資料(可以使用auto_increment自增),最好避免隨機的插入(例如使用uuid作為主鍵)。因為當主鍵的值是順序的時,innodb會把每一條記錄都儲存在上一條記錄的後面,當達到頁的最大填充因子時(預設為15/16),下一條記錄就會寫入新的頁中。而每次插入主鍵的值近似於隨機時,新紀錄根據值的大小要被插入到現有索引頁的中間某個合適位置,此時頁**會導致大量的資料移動並產生碎片,甚至目標頁面可能已經被回寫到磁碟上而從快取中清掉,此時又要從磁碟上讀回來,這增加了很多開銷。

如果乙個索引包含(或者說覆蓋)所有需要查詢的字段的值,我們就稱之為「覆蓋索引」,此時不需要回表操作。其具有以下優點:

mysql有兩種方式可以生成有序的結果:通過排序操作或者按索引順序掃瞄。如果explain出來的type列的值為index,則說明mysql使用了索引掃瞄來做排序。

只有當索引的列順序和order by子句的順序完全一致,並且所有列的排序方向(倒序或正序)都一樣時,mysql才能夠使用索引來對結果做排序。如果查詢需要關聯多張表,則只有當order by子句引用的字段全部為第乙個表時,才能使用索引做排序。order by子句和查詢型查詢的限制是一樣的:需要滿足索引的最左字首的要求,否則mysql都需要執行排序操作,而無法利用索引排序。

Mysql索引與優化 之索引型別

一.mysql索引型別可分為 普通索引 index 僅僅加快查詢速度 主鍵索引 primary key 主鍵索引必是唯一,唯一索引不一定是主鍵索引。唯一索引 unique 行上的值不能重複 全文索引 fulltext 二.建立索引 alter table 表名 add index unique fu...

Mysql索引與優化 之索引型別

一.mysql索引型別可分為 普通索引 index 僅僅加快查詢速度 主鍵索引 primary key 主鍵索引必是唯一,唯一索引不一定是主鍵索引。唯一索引 unique 行上的值不能重複 全文索引 fulltext 二.建立索引 alter table 表名 add index unique fu...

MySQL索引與優化

一 索引的概述與分類 什麼是索引?mysql官方定義 索引是 index 是幫助的mysql高效獲取資料的資料結構,我們可以理解為快速查詢排好序的一種資料結構。索引類似於圖書的目錄索引,可以提高檢索的效率,降低資料庫的io成本。索引的分類 總結 索引就像是一本書的目錄是為了提高檢索的速度。在mysq...