文章目錄
1. 什麼是索引
索引是一個單獨存儲在磁盤上的數據庫結構,它們包含着對數據表裏所有記錄的引用指針
在數據庫中,索引用來加速對錶的查詢,索引技術通過使用快速路徑訪問的方法快速定位數據,減少了磁盤的I/O
可以把索引比作書的目錄,每一張表都要有索引,就像每一本書都應該有目錄一樣。有了索引,數據庫的檢索速度可以大大提高
2. 索引的特點
索引是作用於表查詢的一項技術,因此創建索引時,需要確保該索引是應用在SQL查詢語句的條件,一般作爲where子句的條件。
在表現形式上,索引表現爲一張表,該表保存了主鍵與索引字段,並指向實體表的記錄。索引獨立於數據表存放,但不能獨立存在,必須屬於某個表。索引由數據庫自動維護,數據表被刪除時,該表上的索引自動被刪除。
不過需要注意的是,雖然索引極大地提高了查詢速度,同時卻會降低更新表的速度,如對錶進行insert、update和delete的速度會被降低。 因爲更新表時,數據庫不僅需要更新表數據,還要更新索
引文件,此外由於索引是獨立於表存在的“表”,因此建立索引會佔用一定的磁盤空間。
3. 索引的分類
- 普通索引
最基本的索引,它沒有任何限制,用於加速查詢 - 唯一索引(unique)
索引列的值必須唯一,但允許有空值。如果是組合索列值的組合必須唯一 - 主鍵索引(primary key)
是一種特殊的唯 一索引,一個表只能有一個主鍵,不允許有空值,主鍵索引一般是在表建立的同時自動創建 - 單列索引
指單個字段上創建索引 - 組合索引
指條個字段上創建的索引,只有在查詢條件中使用了創建索引時的第一個字段,索引纔會被使用。使用組合索引時遵循最左前綴集合的規則 - 全文索引(fulltext)
該索引不直接與索引中的值相比較,而是查找文本中的關鍵字 - 空間索引(spatial)
MySQL 5.7.4實驗室版本中,InnoDB存儲引擎新增了對於幾何數據空間索引的支持
4. 索引的設計原則
設計索引應遵循如下原則:
- 只建立適量的索引。 索引並非越多越好,過多的索引會降低表的修改速度以及佔用額外的存儲空間。
- 只在需要大量查詢的表中建立大量索引。 應該避免對經常更新的表進行過多的索引,並且索引中的列要儘可能少。
- 不在數據量小的表建立索引。 數據量小的表沒有必要使用索引
- 不在不同值少的列上建立索引。 如果表的某一列中大部分數據都是重複的,則沒有必要建立索引
- 指定唯一索引。 當表的某一列數據被指定爲unique是,可以建立唯一索引
- 在頻繁操作的列上建立索引。 若想要建立索引,則應選擇頻繁排序(order by)或分組(group by)的列建立索引
5. 創建索引
5.1. 自動創建索引
當在表上定義primary key或者unique約束條件時,數據庫會自動創建一個對應的索引,也就是創建主鍵索引和唯一索引。
5.2. 手動創建索引
5.2.1. 創建表時創建索引
在建表的同時創建索引的語法爲:
create table [表名](
[屬性名1] [數據類型1] [約束1],
...
[屬性名n] [數據類型n] [約束n],
[unique | fulltext | spatial] index|key [索引名](
[屬性名1] [(長度)] [asc | desc],
...
[屬性名n] [(長度)] [asc | desc]
)
);
例如
建立普通索引
create table normal_table(
id int(20) primary key,
username varchar(20),
email varchar(20),
-- 在id列建立普通索引
index normal_index(id)
);
建立唯一索引
create table unique_table(
id int(20) primary key,
username varchar(20),
email varchar(20),
-- 在email列建立唯一索引,並升序排列
unique index uniquel_index(email asc)
);
建立全文索引
create table fulltext_table(
id int(20) primary key,
username varchar(20),
email varchar(20),
-- 在username列建立全文索引
fulltext index fulltext_index(username)
);
建立單列索引
create table single_table(
id int(20) primary key,
username varchar(20),
email varchar(20),
-- 在username列建立索引,索引長度爲9
index single_index(username(9))
);
建立多列索引
create table multi_table(
id int(20) primary key,
username varchar(20),
email varchar(20),
-- 在username列和email列建立索引,索引長度分別爲9和10
index multi_index(
username(9),
email(10)
)
);
5.2.2. 在已經存在的表上創建索引
5.2.2.1. alter語句創建索引
語法:
alter table [表名] add [unique|fulltext|spatial] [index|key] [索引名](
[屬性名1] [(長度)] [asc | desc],
...
[屬性名n] [(長度)] [asc | desc]
);
例如:
建立普通索引
-- 在normal_table表的id列建立名爲normal_index的普通索引
alter table normal_table add index normal_index(id);
建立唯一索引
-- 在unique_table表的username列建立名爲unique_index的唯一索引
alter table unique_table add unique index unique_index(username);
建立多列索引
-- 在multi_table表的username和email列建立名爲multi_index的多列索引
alter table multi_table add index multi_index(username, email);
其他類型的索引同理
5.2.2.2. create語句創建索引
語法:
create unique [unique|fulltext|spatial] index [索引名] ON [表名](
[屬性名1] [(長度)] [asc | desc],
...
[屬性名n] [(長度)] [asc | desc]
);
例如
建立普通索引
-- 在normal_table表的id列建立名爲normal_index的普通索引
create index normal_index on normal_table(id);
建立唯一索引
-- 在unique_table表的username列建立名爲unique_index的唯一索引
create unique index unique_index on unique_table(username);
建立多列索引
-- 在multi_table表的username和email列建立名爲multi_index的多列索引
create index multi_table on multi_table(username, email);
其他類型的索引同理
6. 查看索引
6.1. explain關鍵字查看索引
explain關鍵字用於查看和分析SQL索引使用情況
語法:
explain select * from [表名];
使用裏explain語句後,會返回一張表:
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
---|---|---|---|---|---|---|---|---|---|---|---|
其中對錶中字段的說明可以參考這篇博客:mysql中explain查看sql語句索引使用情況
例如:
-- 查看multi_table表中的所有使用情況
explain select * from multi_table;
結果爲:
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | multi_table | index | multi_table2 | 166 | 1 | 100.00 | Using index |
6.2. show index關鍵字查看索引
show index關鍵字用於查看某一表中的所有索引
語法:
show index from [表名];
使用裏show index語句後,會返回一張表:
Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
其中對錶中字段的說明可以參考這篇博客:MySQL SHOW INDEX 的語法解析
例如:
-- 查看multi_table表中的全部索引
show index from multi_table;
結果爲:
Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
multi_table | 0 | PRIMARY | 1 | id | A | 0 | BTREE | YES | ||||||
multi_table | 1 | multi_index | 1 | username | A | 0 | 9 | YES | BTREE | YES | ||||
multi_table | 1 | multi_index | 2 | A | 0 | 10 | YES | BTREE | YES | |||||
multi_table | 1 | multi_table2 | 1 | username | A | 0 | YES | BTREE | YES | |||||
multi_table | 1 | multi_table2 | 2 | A | 0 | YES | BTREE | YES |
7. 刪除索引
7.1. alter關鍵字刪除索引
語法:
alter table [表名] drop index [索引名];
例如
-- 從multi_table表中刪除multi_index索引
alter table multi_table drop index multi_index;
7.2. drop關鍵字刪除索引
語法:
drop index [索引名] on [表名];
例如
-- 從multi_table表中刪除multi_index索引
drop index multi_index on multi_table;