基礎
什麼是索引
索引是關聯式資料庫中對某一列或多個列的值進行預排序的資料結構。
索引的作用
索引的是用於資料查詢的一種資料結構,常見的用於資料查詢的資料結構,有有序陣列、二叉查詢樹、雜湊表等,這些資料結構都是查詢速度較快的。
面臨的問題
索引設計面臨如下幾個問題:
如何更快的查詢到資料;
是否支援範圍查詢;
如何減少空間的占用;
如何減少磁碟的互動次數,因為資料最終都是存放在磁碟上的,與磁碟的互動閱讀速度越慢;
實現方式
b-tree/b+tree
概念:b-tree指的是b樹,「-」並非減符號,而b+tree指的是b+樹。
在講解b樹和b+樹前,讓我們思考乙個問題,常見的有序陣列、二叉查詢樹等的查詢速度都是log(n),而我們知道mysql中innodb引擎,預設使用的是b+樹作為索引的結構,為什麼呢?
我們知道,記憶體是不安全的易失性儲存,而磁碟才是永續性的儲存介質。而且,由於**因素,磁碟才是最主要的用於資料儲存的,大部分的資料,其實是處於磁碟中,而非記憶體中的。而如果使用有序陣列,儘管查詢速度是log(n),但每次查詢資料,都需要在磁碟中進行log(n)次的磁碟訪問,訪問速度是很慢的。同理,使用二叉樹也存在同樣的問題,大部分的資料都存在於磁碟中,多次訪問磁碟的空間效率更低。那麼,b樹呢?
b樹結構如上圖所示,可以看到,b樹是一棵多叉查詢樹樹,乙個節點可以擁有兩個以上的節點。相比於二叉樹而言,b樹最大的優點在於中間層可以存放於記憶體中,且相同資料量的情況下,b樹的高度低於二叉樹,可以減少查詢的過程,從而加快儲存速度。因此,b樹常用於資料庫和檔案系統的設計中。
上圖所示是b+樹的結構,b+樹是一種類似於b樹的結構,b+樹與b樹的區別有如下幾點:
b樹的非葉子節點上也有完整的行資料,b+樹只在葉子節點上有資料,非葉子節點上只有鍵,優點是記憶體中存放的鍵數量更多,查詢更快。
b+樹的葉子節點上包含所有的鍵,b樹的葉子節點上不一定有所有的鍵。
b+樹的葉子節點通過鍊錶進行連線,範圍查詢更加快速。
hash索引
mysql中的hash索引,如上圖所示,是基於hash表實現的,使用拉鍊法來處理資料衝突,hash索引的檢索效率非常高,而hash索引也存在一些缺點:
hash索引無法處理範圍查詢,範圍查詢速度較慢;
hash索引無法避免排序運算;
hash索引不能利用部分索引鍵查詢,組合索引的場景下,hash索引需要將多個索引鍵進行合併計算hash值,無法單獨利用;
hash索引不可避免地存在表掃瞄地情況,即使通過hash定位到資料,仍然需要對原始資料進行對比,才可以查詢到正確地資料;
hash索引在大量hash值相等地情況下,效能並不一定比b-tree索引高。
由於存在以上缺點,即使hash索引的查詢速度很快,在使用時卻也不一定比b+tree更好。
索引分類
索引型別
主鍵索引
資料庫表中一列或列組合(字段)的值唯一標識表中的每一行。該列稱為表的主鍵。在資料庫中,當定義主鍵時,會自動建立主鍵索引,主鍵索引是唯一索引的特定型別。
普通索引
最基本的索引型別,沒有唯一性之類的限制。
唯一索引
唯一索引是不允許其中任何兩行具有相同索引值的索引。
聚簇索引/非聚簇索引
聚簇索引:也稱聚集索引。表中行的物理順序與鍵值的邏輯(索引)順序相同。乙個表只能包含乙個聚集索引。
非聚簇索引:也稱非聚集索引。在非聚集索引中,資料庫表中記錄的物理順序與索引順序可以不相同。乙個表中只能有乙個聚集索引,但表中的每一列都可以有自己的非聚集索引。
聯合索引
聯合索引是由多個字段組成的索引。其中,只有第乙個欄位是有序的,其他欄位僅在前面字段相等的情況下有序,但從整體的角度而言,是無序的。
效能優化
回表在mysql中,會自動為主鍵建立主鍵索引,同時,主鍵索引上包含所有的資料。而對於其他的所有非主鍵索引,非主鍵索引中只包含索引鍵和主鍵資料。因此在非主鍵索引上查詢到主鍵後,需要通過該主鍵在主鍵索引上查詢資料,這個過程稱為「回表」。
覆蓋索引
如上,當select語句查詢的內容,在非主鍵索引上就已經全部包含,不需要再進入主鍵索引查詢時,稱為「覆蓋索引」。
索引下推
索引查詢時時常帶有where語句,當多個條件並列,且條件在索引資料中包含時,mysql會使用「索引下推」在索引上進行匹配,過濾以減少資料,加快查詢速度。
最左字首匹配
最左字首匹配原則,是乙個應用於聯合索引的非常重要的原則,即查詢時,會按照聯合索引建立的順序,從左到右進行匹配。可以通過以下這幾個特性來理解。
對於聯合索引,mysql 會一直向右匹配直到遇到範圍查詢(> , < ,between,like)就停止匹配。比如 a = 3 and b = 4 and c > 5 and d = 6,如果建立的是(a,b,c,d)這種順序的索引,那麼 d 是用不到索引的,但是如果建立的是 (a,b,d,c)這種順序的索引的話,那麼就沒問題,而且 a,b,d 的順序可以隨意調換。
= 和 in 可以亂序,比如 a = 3 and b = 4 and c = 5 建立 (a,b,c)索引可以任意順序。
如果建立的索引順序是 (a,b)那麼直接採用 where b = 5 這種查詢條件是無法利用到索引的,這一條最能體現最左匹配的特性。
mysql索引回表
先索引掃瞄,再通過id去取索引中未能提供的資料,即為回表。建表mysql create table t id int primary key,k int not null,name varchar 16 index k engine innodb 如果語句是 select from t where ...
mysql索引回表
mysql索引回表概念 1 先通過普通索引 普通索引,唯一索引,組合索引 定位到主鍵值 2 在通過聚集索引定位到行記錄 這就是所謂的回表查詢,先定位主鍵值,再定位行記錄,然後根據行記錄數主鍵id掃瞄索引數,查詢出資料,它的效能較掃一遍索引樹更低 舉例說明 當有乙個表有四個字段,分別是id name,...
Mysql索引 回表 索引覆蓋
1.先說什麼是索引?索引是一種資料結構 不同引擎對索引的實現方式不同,innodb採用b 樹作為索引結構。2.聚簇索引 非聚簇索引索引可分為聚簇索引和非聚簇索引兩種。聚簇索引 clustered index 聚簇索引的資料的物理存放順序與索引順序是一致的。非聚簇索引 二級索引 secondary i...