## 索引
数据库索引类似于书的目录。如果你想快速找到某一个主题,可以先查看目录然后再翻到主题页,而不用从头到尾地去翻阅整本书来查找那个话题。
从一个表中查询数据时,首先 MySQL 检查是否存在索引,如何存在索引,MySQL 使用索引来选择对应的行,而不是扫描整个表的物理行。
强烈建议您在经常查询数据表的列(WHERE 子句条件中的那些列)上创建索引。 MySQL 会在表中所有主键列上自动创建索引。
索引有助于加快查询数据,**为什么不在所有列上使用索引?**
如果在每一列上都创建索引,MySQL必须建立和维护索引表。每当一个修改表中数据时,MySQL 都要重建索引,数据量越大,花费的时间越多,会降低服务器的性能。
### MySQL 索引类型
**从数据结构角度**
- BTREE 索引
- RTREE 索引
- HASH 索引
- FULLTEXT 索引
| 存储引擎 | 索引类型 |
| --- | --- |
| MyISAM | BTREE, RTREE,FULLTEXT |
| InnoDB | BTREE |
| MEMORY | HASH, BTREE |
**从物理存储角度**
- 聚集索引:索引中键值的逻辑顺序决定了行的物理顺序
- 非聚集索引:索引中键值逻辑顺序与物理存储顺序不同
**从逻辑角度**
- 单列索引:单个字段上创建的索引
- 多列索引:复合索引指多个字段上创建的索引
- 唯一索引: 索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一
- 主键索引:主键索引是一种特殊的唯一索引,不允许有空值
- 空间索引:空间索引是对空间数据类型的字段建立的索引
### 索引操作
创建索引语法:
CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name
USING [BTREE|HASH|RTREE]
ON table_name(column_name[(length)][ASC|DESC],...)
给 *employee* 表的 *office_id* 列添加索引,如下所示:
CREATE INDEX idx_office_id ON employee (office_id);
删除索引语法:
DROP INDEX index_name ON table_name
删除 *employee* 表的 *idx_office_id* 索引,如下所示:
DROP INDEX idx_office_id ON employee
参考链接:[MySQL索引背后的数据结构及算法原理](http://blog.codinglabs.org/articles/theory-of-mysql-index.html)