[TOC]
## 索引的作用
>[success] * 索引大大减少服务器需要扫描的数据量
> * 帮助服务器避免排序和临时表
> * 将随机I/O变成顺序I/O
> * 提高查询速度
>[warning] * 降低了写的速度,占用磁盘
> * 5.0版本前只会使用一个索引,5.1引入了索引合并`index merge`
### **使用场景**
* 中到大型表,索引非常有效
* 特大型的表,建立和使用索引的代价也增长,可以使用分区技术来解决
## **索引类型**
> * `B+Tree ` `Hash`
> * 查询时间。B+ Tree为`O(log(n))`,与树的高度有关;Hash为`O(1)`
> * 适用范围。在内存中,红黑树比B树效率更高;若是涉及磁盘操作,则B树更优
## **类型区别**
>[success] * 索引的树型数据结构为什么使用B+树,而非B树或红黑树?
> * * B树需要做局部的中序遍历,可能要跨层访问。
> * * 而**B+树由于所有数据都在叶子结点,不用跨层,同时由于有链表结构,只需要找到首尾,通过链表就能把所有数据取出。**
> * 为什么常用B+ Tree而非Hash作为索引类型?
> * * 数据库中的索引一般是在磁盘上,数据量大的情况可能无法一次装入内存,B+树的设计可以允许数据分批加载,同时树的高度较低,提高查找效率。
> * * 注:哈希索引数据并不是按照索引列的值顺序存储的,故无法用于排序
> * * 哈希索引只支持等值比较查询,如:=、in()、<=>(安全比较运算符,用来做 NULL 值的关系运算),不支持任何范围查询
****
## **索引分类**
> * 普通索引:最基本的索引,没有任何约束限制
> * 唯一索引:与普通索引类似,但是具有唯一性约束
> * 主键索引:特殊的唯一索引,不允许有空置
> * 一个表只能有一个主键索引,可以有多个唯一索引
> * 主键可以与外键构成参照完整性约束,防止数据不一致
> * 组合索引:将多个列组合在一起创建索引,可以覆盖多个列
> * 外键索引:只有InnoDB类型的表才可以使用,保证数据的一致性、完整性和实现级联操作
> * 全文索引:MySql自带的全文索引只能用于MyISAM,并且只能对英文进行全文检索,全文索引(`FULL TEXT`)。目前只有`CHAR`、`VARCHAR`,`TEXT`列上可以创建全文索引。目的为解决`WHERE name LIKE '%word%'`的模糊搜索。
### **索引规约**
> * 业务上具有唯一特性的字段,即使是多个字段的组合,也必须建成唯一索引。
> * 在 varchar 字段上建立索引时,必须指定索引长度,没必要对全字段建立索引,根据实际文本区分度决定索引长度即可。count(distinct left(列名, 索引长度))/count(*)计算区分度
> * SQL 性能优化的目标:至少要达到 range 级别,要求是 ref 级别,如果可以是 consts最好。
**创建原则**
> * 最适合索引的列是出现在`where`子句中的列,或连接子句中的列而不是出现在`select`关键字后的列
> * 索引列的基数越大,索引的效果越好
> * 对字符串进行索引,应该制定一个前缀长度,可以节省大量的索引空间
**注意事项**
>[danger]
> * 组合索引遵循前缀原则
> * `like`查询时, `%` 不能在前, 可以使用全文索引
> * `column is null` 可以使用索引
> * 如果MySql估计使用索引比全表扫描更慢,会放弃使用索引
> * 如果 `or`前的条件中的列有索引,后面的没有,索引都不会被用到
> * 列类型是字符串,查询时给值加引号,否则索引失效
### **覆盖索引**
* 查询的数据列从索引中就能够获取到,不必从数据表中读取
> 了解覆盖索引之前我们先大概了解一下什么是聚集索引(主键索引)和辅助索引(二级索引)
聚集索引(主键索引):
聚集索引就是按照每张表的主键构造一颗B+树,同时叶子节点中存放的即为整张表的记录数据。
聚集索引的叶子节点称为数据页,聚集索引的这个特性决定了索引组织表中的数据也是索引的一部分。
辅助索引(二级索引):
非主键索引,叶子节点=键值+书签。Innodb存储引擎的书签就是相应行数据的主键索引值。
>* 解释一: 就是select的数据列只用从索引中就能够取得,不必从数据表中读取,换句话说查询列要被所使用的索引覆盖。
> * 解释二: 索引是高效找到行的一个方法,当能通过检索索引就可以读取想要的数据,那就不需要再到数据表中读取行了。如果一个索引包含了(或覆盖了)满足查询语句中字段与条件的数据就叫 做覆盖索引。
>* 解释三:是非聚集组合索引的一种形式,它包括在查询里的Select、Join和Where子句用到的所有列(即建立索引的字段正好是覆盖查询语句\[select子句\]与查询条件\[Where子句\]中所涉及的字段,也即,索引包含了查询正在查找的所有数据)。
>[danger] * 不是所有类型的索引都可以成为覆盖索引。覆盖索引必须要存储索引的列,而哈希索引、空间索引和全文索引等都不存储索引列的值,所以MySQL只能使用B-Tree索引做覆盖索引
>[danger] * 索引是通过二叉树的数据结构来描述的,我们可以这么理解聚簇索引:索引的叶节点就是数据节点。而非聚簇索引的叶节点仍然是索引节点,只不过有一个指针指向对应的数据块。
- 简介
- PHP
- 字符串函数
- 数组函数
- 正则
- 加密函数
- 面向对象
- 关键字
- 设计模式
- 魔术方法
- 机制扩展
- 会话机制
- PHP框架
- laravel
- 问题
- swoole
- easyswoole
- workerman
- 数据库
- Sphinx
- MongoDB
- MemCache
- Redis
- 基础操作
- 数据类型
- 持久化
- 分布式锁
- 内存模型
- redis高级特性
- MySql
- 基础操作
- 数据类型
- 数据表引擎
- 锁机制
- 事务处理
- 存储过程
- 触发器
- 索引
- 关联查询
- 分析SQL语句-优化查询
- 分区分表
- 主从复制
- MySql安全性
- 网络协议
- HTTP
- header详解
- 状态码
- nginx-配置
- 逻辑算法
- 时间和空间复杂度
- 常见算法
- 数据结构
- 核心
- 进程、线程、协程
- 存储容量-计量单位
- 开发软件及配置
- 版本控制器
- Git
- Fidder
- Fidder-Android7
- 自动化部署
- Jenkins
- supervisor
- Elasticsearch
- LogStash
- RabbitMQ
- AB测试
- JAVA-JDK
- FileBeat
- PhpStorm
- Composer
- Linux
- API安全
- 高并发及大流量相关概念
- 网站优化
- WEB
- Electron