數據庫的每一個知識點真要詳細介紹的話都可以寫成一本小冊子,索引也不例外,但沒那個必要。作為數據分析師或非數據庫開發人員,所需了解的僅僅是下面這些知識點。
什么是索引
索引是為了加速對數據庫表中數據行的檢索而創建的一種分散的存儲結構。這話有些人可能看著拗口,但如果將索引比喻成字典的目錄那就很好理解了。借助對目錄的了解可以加深我們對索引的理解。
上表所列的是二者的共性特點,理解這些后就對索引的優缺點有了一個大致的認識。
索引原理
索引按照存儲結構類型可主要分為Btree(也稱B樹)和Hash兩大類型,其中Btree最為常用。MySQL數據庫默認的引擎是InnoDB引擎,該引擎的表默認創建的是Btree索引。所以,主要掌握該索引就夠了。
Btree是樹結構索引,它的原理就是通過為表創建樹形狀的存儲結構從而加快查詢效率。它經歷了二叉樹、平衡樹、B-樹、B+樹的優化歷程。掌握了這一變化歷程,也就掌握了B樹索引的原理。
我們以斐波那契數列的前8位數[1,2,3,5,8,13,21]作為索引值,看看不同樹結構下會是怎樣的存儲結構。
(1)二叉樹
下圖的存儲結構就是二叉樹,按照這個結構,我們查詢某一個數字最多只需要5次,也就是樹的高度。
二叉樹具有如下特點:
- 每個結點都包含一個元素以及n個子樹,0≤n≤2;
- 左子樹的值要小于父結點,右子樹的值要大于父結點。
但二叉樹存在著一個缺點,隨著后續的數字添加進來,會全部添加到右子樹,該樹就會嚴重右偏,退化成差不多一個鏈表了,查詢效率也就大大降低了。
(2)平衡樹
平衡樹是一種特殊的二叉樹,它是為了解決二叉樹偏科的問題而誕生的。它除了具備二叉樹的兩個特性外,還具有左右兩個子樹高度差不超過1的特性,并且左右兩個子樹都是一棵平衡二叉樹。
但平衡樹中每個節點只能有一個值,在數據量大的情況下會需要多個節點,樹的深度很很大,這就會大量增加和磁盤的IO次數,影響查詢性能。
(3)B-樹
B-樹的節點就可以不止有一個數了,除了有鍵值,還存有數據。相比平衡樹,它的形狀屬于更矮更胖,與磁盤的IO次數就會大大降低。
但也正是由于節點中包含了數據,導致每次從磁盤讀入到內存的鍵值數就會降低,在這種情形下還是會一定程度增加磁盤的IO次數,從而影響查詢效率。
(4)B+樹
B+樹是對B-樹的優化,所有的非葉子節點只存儲鍵值信息,所有數據都存在葉子節點中,葉子節點之間都有一個鏈指針。
由于數據全部存儲在葉子節點中,非葉子節點只包含鍵值,每次讀入內存的鍵值相對B-樹來說就會增加,從而降低磁盤IO次數、提升查詢效率。
這也是為什么目前索引均主要是采用B+樹結構的原因。
索引類型
索引一般可分為普通索引、唯一索引、主鍵索引、組合索引和全文索引五類。
(1)普通索引
這是最基本的索引,沒有任何限制,如下是常用的普通索引增刪查改方式。
create index indexname on test_one(column_one);--建立索引
alter table test_one add index indexname(column_one);--建立索引
drop index indexname on test_one;--刪除索引
show index from test_one;--查看表的索引
select * from information_schema.statistics where table_schema='test_one';--查看數據庫的索引
(2)唯一索引
與普通索引類似,不同的就是索引列值必須唯一,但允許有空值。例如,可以對用戶的身份證號碼字段建立唯一索引。關于它的相關語句就是需要添加unique字段,僅以創建為例,其它以此類推。
create unique index indexname on test_one(column_one);--建立索引
(3)主鍵索引
主鍵索引也稱聚集索引,它與其它索引的區別在于其葉子節點存放的數據是一整行數據,而其它索引存放的只是具體的某一個數據。
如果表在創建時未定義主鍵,MySQL會取第一個唯一索引而且只含非空的列作為主鍵,并用它作為聚集索引。如果沒有這樣的列,就會就自動產生一個這樣的ID值,它有六個字節,而且是隱藏的,使其作為聚集索引。當然,在表創建好之后,也可通過指定主鍵來創建主鍵索引。
alter table test_one add primary key(column_one);
(4)組合索引
這是指在多個字段上創建的索引,但要注意只有在查詢條件中使用了創建索引時的第一個字段,組合索引才會被使用。
alter table test_one add index indexname(column_one,column_two);
(5)全文索引
全文索引主要用來查找文本中的關鍵字,而不是直接與索引中的值相比較。例如,對備注信息就可以建立全文索引。
alter table test_one add fulltext indexname(column_one);
注意事項
數據分析師更多地是在寫查詢SQL時使用索引,這時需注意以下這些細節:
- 以%開頭的like查詢無法使用索引;
- 數據類型出現隱式轉換時無法使用索引;
- 不滿足最左原則的復合索引查詢無法使用索引;
- or分隔開的條件中若有一列沒有索引,則涉及到的索引都無法使用;
- 在索引列使用函數或進行運算的查詢無法使用索引;
- not in和<>的查詢無法使用索引。
結語
文中所介紹的索引知識點,對于數據分析師了解索引內容而言是足夠了的。但也畢竟只是在廣度上做了介紹,就有如限定了考試范圍,而在有些地方的深度介紹還不夠,這就需要每個人結合自身實際情況去查漏補缺了!