前言:
索引是mysql資料庫中的重要物件之一,索引的目的在於提高查詢效率。可以模擬字典中的目錄,查詢字典內容時可以根據目錄查詢到資料的存放位置,然後直接獲取即可。索引是表的目錄,在查詢內容之前可以先在目錄中查詢索引位置,以此快速定位查詢資料。需要說明的是,mysql支援諸多儲存引擎,而各種儲存引擎對索引的支援也各不相同。為了避免混亂,本文將只關注於innodb引擎下的b+tree索引。
1.索引結構及原理
首先我們要知道索引是一種資料結構。在innodb中,每個索引其實都是一顆b+樹,b+樹是為了磁碟及其他儲存輔助裝置而設計的一種平衡查詢樹(不是二叉樹),在b+樹中,所有的資料都在葉子節點,且每乙個葉子節點都帶有指向下乙個節點的指標,形成了乙個有序的鍊錶。一般情況下資料庫的b+樹的高度一般在2~4層,這就是說找到某一鍵值的行記錄最多需要2到4次邏輯io,下圖簡單展示了b+樹索引的結構。
2.索引的分類及建立方法
在innodb中,表都是根據主鍵順序以索引的形式存放的,這種儲存方式的表稱為索引組織表。根據葉子節點的內容,索引型別分為主鍵索引和非主鍵索引。主鍵索引的葉子節點存的是整行資料。在innodb裡,主鍵索引也被稱為聚簇索引(clustered index)。非主鍵索引的葉子節點內容是索引列和主鍵的值。在innodb裡,非主鍵索引也被稱為二級索引(secondary index)或輔助索引
一張innodb表必須有乙個聚簇索引,當有主鍵時,會以主鍵作為聚簇索引;如果沒有顯式定義主鍵,innodb會選擇乙個唯一的非空索引代替。如果沒有這樣的索引,則mysql自動為innodb表生成乙個隱含字段作為主鍵。除聚簇索引外的其他索引都可稱為二級索引,比如我們常用到的唯一索引、普通索引、聯合索引等。
上面講過聚簇索引的葉子節點存的是整行資料,當某條查詢使用的是聚簇索引時,只需要掃瞄聚簇索引一顆b+樹即可得到所需記錄,如果想通過二級索引來查詢完整的記錄的話,需要通過回表操作,也就是在通過二級索引找到主鍵值之後再到聚簇索引中查詢完整的記錄。也就是說,基於非主鍵索引的查詢需要多掃瞄一棵索引樹。因此,我們在應用中應該盡量使用主鍵查詢。
下面介紹下索引的建立、刪除等操作方法。
# 建表時指定索引
create table `t_index` (
`increment_id` int(11) not null auto_increment comment '自增主鍵',
`col1` int(11) not null,
`col2` varchar(20) not null,
`col3` varchar(50) not null,
`col4` int(11) not null,
primary key (`increment_id`),
unique key `uk_col1` (`col1`),
key `idx_col2` (`col2`)
) engine=innodb default charset=utf8 comment='測試索引';
# 建立索引(兩種方法)
# 普通索引
alter table `t_index` add index idx_col3 (col3);
create index idx_col3 on t_index(col3);
# 唯一索引
alter table `t_index` add unique index uk_col4 (col4);
create unique index uk_col4 on t_index(col4);
# 聯合索引
alter table `t_index` add index idx_col3_col4 (col3,col4);
create index idx_col3_col4 on t_index(col3,col4);
# 刪除索引
alter table `t_index` drop index uk_col4;
drop index idx_col3_col4 on t_index;
3.索引的優缺點及使用建議
索引的優點顯而易見是可以加速查詢,但建立索引也是有代價的。首先每建立乙個索引都要為它建立一棵b+樹,會占用額外的儲存空間;其次當對表中的資料進行增加、刪除、修改時,索引也需要動態的維護,降低了資料的維護速度。所以,索引的建立及使用時有原則的,下面給出幾點索引使用的建議:
顯式建立主鍵索引,建議使用自增id作為主鍵。
只為用於搜尋、排序、分組、連線的列建立索引。
對經常更新的表避免建立過多的索引。
建立聯合索引時,可選擇性高的列放在前面。
盡量不要在可選擇性差的列上建索引,如:性別、狀態列等。
盡量使用覆蓋索引進行查詢,避免回表帶來的效能損耗。(覆蓋索引包含要查詢的所有列)
select後面只寫查詢需要用到的字段,去掉不需要的字段。
定位並刪除表中的重複和冗餘索引。
總結:其實很早就想寫篇索引相關的文章,但一直沒有完成,因為關於索引的文章太多了!大多也是大同小異,而且想深入解析索引需要演算法相關知識,講明白索引並不是一件容易的事。當然,本篇文章也寫得很普通,只是介紹下在專案開發中實用的一些知識,索引的內容還有很多,需要我們不斷的去學習。
mysql 雜湊索引 MySQL索引之雜湊索引
雜湊索引 hash index 建立在雜湊表的基礎上,它只對使用了索引中的每一列的精確查詢有用。對於每一行,儲存引擎計算出了被索引的雜湊碼 hash code 它是乙個較小的值,並且有可能和其他行的雜湊碼不同。它把雜湊碼儲存在索引中,並且儲存了乙個指向雜湊表中的每一行的指標。在mysql中,只有me...
mysql主鍵索引 MySQL索引之主鍵索引
在mysql裡,主鍵索引和輔助索引分別是什麼意思,有什麼區別?上次的分享我們介紹了聚集索引和非聚集索引的區別,本次我們繼續介紹主鍵索引和輔助索引的區別。1 主鍵索引 主鍵索引,簡稱主鍵,原文是primary key,由乙個或多個列組成,用於唯一性標識資料表中的某一條記錄。乙個表可以沒有主鍵,但最多只...
mysql聚集索引 MySQL索引之聚集索引介紹
在mysql裡,聚集索引和非聚集索引分別是什麼意思,有什麼區別?在mysql中,innodb引擎表是 聚集 索引組織表 clustered index organize table 而myisam引擎表則是堆組織表 heap organize table 也有人把聚集索引稱為聚簇索引。當然了,聚集索...