索引介紹
索引是什麼
官方介紹索引是幫助MySQL高效獲取數據
的數據結構
。更通俗的說,數據庫索引好比是一本書前面的目
錄,能加快數據庫的查詢速度
。
索引的優勢和劣勢
優勢:
-
可以
提高數據檢索的效率,降低數據庫的IO成本
,類似於書的目錄。 – 檢索 -
通過
索引列對數據進行排序,降低數據排序的成本
,降低了CPU的消耗。 --排序- 被索引的列會自動進行排序,包括【單列索引】和【組合索引】,只是組合索引的排序要複雜一些。
- 如果按照索引列的順序進行排序,對應order by語句來說,效率就會提高很多。
- where 索引列在存儲引擎層 處理 - 索引條件下推 ICP(
Index Condition Push
)。 - 覆蓋索引 select 字段 字段是索引。
劣勢:
- 索引會佔據磁盤空間。
- 索引雖然會提高查詢效率,但是會
降低更新表的效率
,比如每次對錶的增刪改操作。 - Mysql不僅要保存數據,還有保存或者跟新對應的索引文件。
索引的分類
- 單列索引
- 組合索引
- 全文索引
- 空間索引
- 位圖索引(Oracle)
索引的使用
創建索引
- 單列索引之普通索引
CREATE INDEX index_name ON table(column(length));
ALTER TABLE table_name ADD INDEX index_name (column(length));
- 單列索引之唯一索引
CREATE UNIQUE INDEX index_name ON table(column(length));
ALTER TABLE table_name ADD UNIQUE INDEX index_name(column);
- 單列索引之全文索引
CREATE UNIQUE INDEX index_name ON table(column(length));
ALTER TABLE table_name ADD UNIQUE INDEX index_name(column);
- 組合索引
CREATE FULLTEXT INDEX index_name ON table(column(length));
ALTER TABLE table_name ADD FULLTEXT INDEX index_name(column);
刪除索引
DROP INDEX index_name ON table;
查看索引
SHOW INDEX FROM table_name;
索引原理分析
索引的存儲結構
索引結構
- 索引是在
存儲引擎中實現
的,也就是說不同的存儲引擎,會使用不同的索引 MyISAM
和InnoDB
存儲引擎:只支持B+TREE
索引, 也就是說默認使用BTREE,不能夠更換MEMORY/HEAP
存儲引擎:支持HASH
和BTREE
索引
B樹和B+樹
數據結構示例網站:
https://www.cs.usfca.edu/~galles/visualization/Algorithms.html
B樹圖示
B樹是爲了磁盤或其它存儲設備而設計的一種多叉(下面你會看到,相對於二叉,B樹每個內結點有多個
分支,即多叉)平衡查找樹。 多叉平衡
- B樹的
高度一般都是在2-4這個高度
,樹的高度直接影響IO讀寫的次數
。 - 如果是
三層樹結構支撐的數據可以達到20G
,如果是四層樹結構支撐的數據可以達到幾十T
。
B+Tree對比BTree和的優勢
- 磁盤讀寫代價更低
一般來說B+Tree比BTree更適合實現外存的索引結構,因爲存儲引擎的設計專家巧妙的利用了外存(磁盤)的存儲結構,即磁盤的最小存儲單位是扇區(sector),而操作系統的塊(block)通常是整數倍的sector,操作系統以頁(page)爲單位管理內存,一頁(page)通常默認爲4K,數據庫的頁通常設置爲操作系統頁的整數倍,因此索引結構的節點被設計爲一個頁的大小
,然後利用外存的“預讀取”原則,每次讀取
的時候,把整個節點的數據讀取到內存中
,然後在內存中查找,已知內存的讀取速度是外存讀取I/O速度的幾百倍,那麼提升查找速度
的關鍵就在於儘可能少的磁盤I/O
,那麼可以知道,每個節點中的key個數越多,那麼樹的高度越小,需要I/O的次數越少
,因此一般來說B+Tree比BTree更快,因爲B+Tree的非葉節點中不存儲data,就可以存儲更多的key。 - 查詢速度更穩定
由於B+Tree非葉子節點不存儲數據(data),因此所有的數據都要查詢至葉子節點,而葉子節點的高度都是相同
的,因此所有數據的查詢速度都是一樣的
。 - B+樹
只有葉子節點纔會存儲數據
,而且存儲的數據都是在一行上,而且這些數據都是有指針指向
的,也就是有順序的。
非聚集索引(MyISAM)
主鍵索引
輔助索引(次要索引)
聚集索引(InnoDB)
主鍵索引
- 若表沒建立主鍵,Mysql會自動找唯一字段或自動生成僞列當主鍵
- 主鍵的創建建議使用整數,不要使用大字符串(UUID等),因爲這種字符本身無序。
輔助索引(次要索引)
- 從輔助索引樹上找到主鍵後在主鍵索引樹下找到數據稱爲(
回表
) - 在可能的情況下優化能避免回表,利用組合索引即在當前輔助索引樹中包含需要查詢的字段,則可以避免回表稱爲(
索引覆蓋
)
索引樹
利用組合索引 完成覆蓋索引(利用組合索引完成在輔助索引樹的遍歷,不回表)