索引index:是幫助 Mysql 高效獲取資料 的 有序的資料結構,在資料之外,資料庫系統維護著的滿足特定查詢演演算法的資料結構,這些資料結構以某種方式參照(指向)資料,這樣就可以在這些資料結構上實現高階查詢演演算法,這種資料結構就是索引
Mysql的索引是在儲存引擎層實現的,不同的儲存引擎有不同的結構,主要包含一下幾種
說明1:實際中的索引是沒有使用二元樹的,因為二元樹具有一下的弊端
說明2:當順序插入時,會形成一個連結串列,查詢效能大大降低,巨量資料量的情況下,層級較深,檢索速度慢。
說明3:特殊二元樹紅黑樹當做索引是,巨量資料量情況下,層級比較深,檢索速度慢
以一個最大度數(max-degree)為5(5階)的b樹為例(每個節點最多儲存4個key,5個指標)
說明:B樹的資料會存在每個節點上,而節點存在頁(2.6 Mysql索引對B+樹的優化有說明)上面,每頁的大小為16K,這樣每個頁能存放的索引就比較少,導致同樣資料體積小,層級要比B+樹深。
以一個最大度數(max-degree)為4(4階)的b+樹為例
說明:對比較與B樹
1、所有的資料都會出現在葉子節點上
2、葉子節點形成一個單向連結串列
Mysql索引資料結構對經典的B+樹進行了優化,在原來的B+樹基礎上,增加了一個指向相鄰葉子節點的連結串列指標,就行了帶有順序指標的B+樹,提高了區間存取的效能
說明:每頁在InnoDB中預設16K
雜湊索引就是採用一定的hash演演算法,將鍵值換成新的hash值,對映到對應的槽位上,然後儲存在hash表中
說明:如果兩個(或者多個)鍵對映到同一個槽位上,他們就產生了hash衝突,也稱hash碰撞,可以通過連結串列來解決
針對於表中主鍵建立的索引,預設自動建立,只能有一個, 關鍵字:primary
避免同一個表中某資料列中的值重複,可以有多個,關鍵字:unique
快速定位特定資料,可以有多個,
全文索引查詢的是文字中的關鍵字,而不是比較索引中的值,可以有多個,fulltext
在InnoDB中,根據索引的儲存形式劃分的,將資料儲存與索引放到一起,索引結構的葉子節點儲存了行資料,必須有,而且只有一個
在InnoDB中,根據索引的儲存形式劃分的,將資料與索引分開儲存,索引結構的葉子節點關聯的是對應的主鍵,可以存在多個
說明:聚集索引下面存放的是整行的資料,二級索引下面存放的對應的主鍵,要不然聚集索引下存放了整行資料,二級索引下也放整行資料,就會很冗餘
說明1:首先根據name欄位走二級索引
說明2:找到Arm對應的id=10
說明3:然後再根據id=10找到對應的資料
說明4:整個過程也叫做回表查詢
show index from 表名
範例:
mysql> show index from account; +---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+ | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression | +---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+ | account | 0 | PRIMARY | 1 | id | A | 4 | NULL | NULL | | BTREE | | | YES | NULL | +---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+ 1 row in set (0.00 sec)
說明:account 有一個主鍵索引
create [unique | fulltext] index 索引名 on 表名(索引的列名, ..);
說明1:如果建立索引的欄位是唯一的,值都不重複,可以加unique約束,說明這是一個唯一欄位索引
說明2:fulltext 是全文檢索索引,主要針對大的文字欄位
mysql> create index name_idx on account(name); Query OK, 0 rows affected (0.03 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> show index from account; +---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+ | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression | +---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+ | account | 0 | PRIMARY | 1 | id | A | 4 | NULL | NULL | | BTREE | | | YES | NULL | | account | 1 | name_idx | 1 | name | A | 4 | NULL | NULL | YES | BTREE | | | YES | NULL | +---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+ 2 rows in set (0.01 sec)
說明1:這就建立了一個名為name_idx的索引
drop index 索引名 on 表名
範例
mysql> drop index name_idx on account; Query OK, 0 rows affected (0.00 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> show index from account; +---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+ | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression | +---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+ | account | 0 | PRIMARY | 1 | id | A | 4 | NULL | NULL | | BTREE | | | YES | NULL | +---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+ 1 row in set (0.00 sec)
說明:這就刪除了一個索引
後面的文章會繼續介紹索引的使用和設計原則