Skip to content

Commit

Permalink
✏更新 MySQL 索引
Browse files Browse the repository at this point in the history
  • Loading branch information
0xcaffebabe committed Jul 20, 2021
1 parent 16ed20a commit 787cb8e
Showing 1 changed file with 27 additions and 15 deletions.
42 changes: 27 additions & 15 deletions 中间件/数据库/mysql/索引.md
Expand Up @@ -61,7 +61,7 @@ B+树中叶子节点中包含了key和value,非叶子节点中只是包含了k

- 回表:使用索引就能完成查询 无需扫描表数据
- 最左匹配:在检索数据时从联合索引的最左边开始匹配
- 索引下推:通过索引中存储的数据判断当前索引对应的数据是否符合条件,只有符合条件的数据才将整行数据查询出来
- 索引下推:MySQL服务器将这一部分判断条件传递给存储引擎,然后由存储引擎通过判断索引是否符合MySQL服务器传递的条件 存储引擎最后再将数据返回给服务器

### 分类

Expand Down Expand Up @@ -160,10 +160,18 @@ explain select name,age,pos from staffs where name = 'July' and age = 25 and pos

聚簇索引:不是单独的索引类型,而是一种数据存储方式,指的是数据行跟相邻的键值紧凑的存储在一起

![屏幕截图 2021-03-09 172129](/assets/屏幕截图%202021-03-09%20172129.png)
![聚簇索引的数据分布](/assets/屏幕截图%202021-03-09%20172129.png)

在InnoDB中,默认会选择主键来做举出索引,若没有主键,会生成一个隐藏的主键,主键最好使用自增的数值类型,这样在插入效率及空间占用都会最优

非聚簇索引:数据文件跟索引文件分开存放

### 使用索引排序

EXPLAIN的type为index时 代表使用索引扫描做排序

只有当ORDER BY子句的列都是索引且排序方向一致时,才会使用索引排序

### 覆盖索引

如果一个索引包含所有需要查询的字段的值,称之为覆盖索引,当需要的数据被索引覆盖时,就不必回表查询。
Expand All @@ -176,6 +184,10 @@ MySQL中只能使用B树索引做覆盖索引
EXPLAIN SELECT store_id,film_id FROM inventory; -- Extra:Using index 代表可以做覆盖索引
```

### 压缩索引

MyISAM会使用前缀压缩的方式将降低索引空间占用,从而使更多的索引可以放入内存。但代价是牺牲了CPU的运算时间。

### MyISAM和InnoDB对B+Tree的使用

MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。而在InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录
Expand Down Expand Up @@ -203,37 +215,37 @@ innodb
进行查询时,索引列不能是表达式的一部分,也不能是函数的参数

```sql
SELECT a FROM B WHERE a+3 = 6; -- a不能作为索引
SELECT a FROM B WHERE a+3 = 6; -- 无法用到索引
```

### 主键索引
### 前缀索引

可以选择开始的部分字符串来进行索引,索引的列的不重复值数量/总数量=索引的选择性 选择性越高 查询效率越好

为了达到索引空间与查询性能的平衡 需要选取一个折中的前缀索引长度

尽量使用主键查询,而不是其他索引,因此主键查询不会触发回表查询
BLOB、TEXT 和 VARCHAR 类型的列,必须使用前缀索引

前缀索引无法进行ORDER BY 或者GEOUP BY,也无法进行覆盖扫描。

有时候又需要后缀索引,为了达成这个目的,一种hack的方式是把字符串反转后进行存储

### 多列索引

多个列作为条件进行查询时,使用多列索引比使用多个单列索引性能更好

MySQL会进行一项称为索引合并的策略,一定程度上可以使用多个单列索引来定位指定的行

### 组合索引
#### 组合索引

当一个索引不止一个列时,只有当最左索引(索引的第一个列)出现时,才会走索引查询

### 索引列的顺序
#### 索引列的顺序

在不考虑排序和分组时,让选择性最强的索引列放在前面

一个列比另外一个列更越能确定一条数据,则前者选择性更强。但还有一种情况就是数据分布不均匀,也有可能造成索引的效果非常差

### 前缀索引

BLOB、TEXT 和 VARCHAR 类型的列,必须使用前缀索引,只索引开始的部分字符

前缀索引无法进行ORDER BY 或者GEOUP BY,也无法进行覆盖扫描。

有时候又需要后缀索引,为了达成这个目的,一种hack的方式是把字符串反转后进行存储

### 覆盖索引

索引包含所有需要查询的字段的值
Expand Down

0 comments on commit 787cb8e

Please sign in to comment.