Skip to content

Commit 766fd3b

Browse files
committed
update docs
1 parent 846bd3b commit 766fd3b

File tree

9 files changed

+268
-237
lines changed

9 files changed

+268
-237
lines changed

docs/sql/mysql/mysql-config.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
55
<!-- TOC depthFrom:2 depthTo:3 -->
66

7-
- [一、基本配置](#一基本配置)
8-
- [二、配置项说明](#二配置项说明)
9-
- [参考资料](#参考资料)
7+
- [1. 基本配置](#1-基本配置)
8+
- [2. 配置项说明](#2-配置项说明)
9+
- [3. 参考资料](#3-参考资料)
1010

1111
<!-- /TOC -->
1212

13-
## 一、基本配置
13+
## 1. 基本配置
1414

1515
```ini
1616
[mysqld]
@@ -55,7 +55,7 @@ socket = /var/lib/mysql/mysql.sock
5555
port = 3306
5656
```
5757

58-
## 二、配置项说明
58+
## 2. 配置项说明
5959

6060
```ini
6161
[client]
@@ -477,7 +477,7 @@ auto-rehash
477477
socket = /var/lib/mysql/mysql.sock
478478
```
479479

480-
## 参考资料
480+
## 3. 参考资料
481481

482482
- [《高性能 MySQL》](https://item.jd.com/11220393.html)
483483
- [Mysql 配置文件/etc/my.cnf 解析](https://www.jianshu.com/p/5f39c486561b)

docs/sql/mysql/mysql-faq.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44
55
<!-- TOC depthFrom:2 depthTo:3 -->
66

7-
- [参考资料](#参考资料)
7+
- [1. 为什么表数据删掉一半,表文件大小不变](#1-为什么表数据删掉一半表文件大小不变)
8+
- [2. 参考资料](#2-参考资料)
89

910
<!-- /TOC -->
1011

11-
## 为什么表数据删掉一半,表文件大小不变
12+
## 1. 为什么表数据删掉一半,表文件大小不变
1213

1314
【问题】数据库占用空间太大,我把一个最大的表删掉了一半的数据,怎么表文件的大小还是没变?
1415

@@ -34,7 +35,7 @@
3435

3536
要达到收缩空洞的目的,可以使用重建表的方式。
3637

37-
## 参考资料
38+
## 2. 参考资料
3839

3940
- [《高性能 MySQL》](https://book.douban.com/subject/23008813/)
4041
- [MySQL 实战 45 讲](https://time.geekbang.org/column/intro/139)

docs/sql/mysql/mysql-index.md

Lines changed: 52 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,38 @@
88

99
<!-- TOC depthFrom:2 depthTo:3 -->
1010

11-
- [一、索引简介](#一索引简介)
12-
- [索引的优缺点](#索引的优缺点)
13-
- [何时使用索引](#何时使用索引)
14-
- [二、索引的数据结构](#二索引的数据结构)
15-
- [哈希索引](#哈希索引)
16-
- [B 树索引](#b-树索引)
17-
- [全文索引](#全文索引)
18-
- [空间数据索引](#空间数据索引)
19-
- [三、索引的类型](#三索引的类型)
20-
- [四、索引的策略](#四索引的策略)
21-
- [索引基本原则](#索引基本原则)
22-
- [独立的列](#独立的列)
23-
- [覆盖索引](#覆盖索引)
24-
- [前缀索引](#前缀索引)
25-
- [最左前缀匹配原则](#最左前缀匹配原则)
26-
- [= 和 in 可以乱序](#-和-in-可以乱序)
27-
- [五、索引最佳实践](#五索引最佳实践)
28-
- [参考资料](#参考资料)
11+
- [1. 索引简介](#1-索引简介)
12+
- [1.1. 索引的优缺点](#11-索引的优缺点)
13+
- [1.2. 何时使用索引](#12-何时使用索引)
14+
- [2. 索引的数据结构](#2-索引的数据结构)
15+
- [2.1. 哈希索引](#21-哈希索引)
16+
- [2.2. B 树索引](#22-b-树索引)
17+
- [2.3. 全文索引](#23-全文索引)
18+
- [2.4. 空间数据索引](#24-空间数据索引)
19+
- [3. 索引的类型](#3-索引的类型)
20+
- [3.1. 主键索引(`PRIMARY`](#31-主键索引primary)
21+
- [3.2. 唯一索引(`UNIQUE`](#32-唯一索引unique)
22+
- [3.3. 普通索引(`INDEX`](#33-普通索引index)
23+
- [3.4. 全文索引(`FULLTEXT`](#34-全文索引fulltext)
24+
- [3.5. 联合索引](#35-联合索引)
25+
- [4. 索引的策略](#4-索引的策略)
26+
- [4.1. 索引基本原则](#41-索引基本原则)
27+
- [4.2. 独立的列](#42-独立的列)
28+
- [4.3. 覆盖索引](#43-覆盖索引)
29+
- [4.4. 使用索引来排序](#44-使用索引来排序)
30+
- [4.5. 前缀索引](#45-前缀索引)
31+
- [4.6. 最左前缀匹配原则](#46-最左前缀匹配原则)
32+
- [4.7. = 和 in 可以乱序](#47--和-in-可以乱序)
33+
- [5. 索引最佳实践](#5-索引最佳实践)
34+
- [6. 参考资料](#6-参考资料)
2935

3036
<!-- /TOC -->
3137

32-
## 一、索引简介
38+
## 1. 索引简介
3339

3440
**_索引优化应该是查询性能优化的最有效手段_**
3541

36-
### 索引的优缺点
42+
### 1.1. 索引的优缺点
3743

3844
B+ 树索引,按照顺序存储数据,所以 Mysql 可以用来做 ORDER BY 和 GROUP BY 操作。因为数据是有序的,所以 B+ 树也就会将相关的列值都存储在一起。最后,因为索引中存储了实际的列值,所以某些查询只使用索引就能够完成全部查询。
3945

@@ -51,7 +57,7 @@ B+ 树索引,按照顺序存储数据,所以 Mysql 可以用来做 ORDER BY
5157
- **索引需要占用额外的物理空间**,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立组合索引那么需要的空间就会更大。
5258
- 写操作(`INSERT`/`UPDATE`/`DELETE`)时很可能需要更新索引,导致数据库的写操作性能降低。
5359

54-
### 何时使用索引
60+
### 1.2. 何时使用索引
5561

5662
> 索引能够轻易将查询性能提升几个数量级。
5763
@@ -68,9 +74,9 @@ B+ 树索引,按照顺序存储数据,所以 Mysql 可以用来做 ORDER BY
6874
- 列名不经常出现在 `WHERE` 或连接(`JOIN`)条件中 - 索引就会经常不命中,没有意义,还增加空间开销。
6975
- 对于特大型表,建立和使用索引的代价将随之增长。可以考虑使用分区技术或 Nosql。
7076

71-
## 二、索引的数据结构
77+
## 2. 索引的数据结构
7278

73-
### 哈希索引
79+
### 2.1. 哈希索引
7480

7581
> Hash 索引只有精确匹配索引所有列的查询才有效。
7682
@@ -89,7 +95,7 @@ B+ 树索引,按照顺序存储数据,所以 Mysql 可以用来做 ORDER BY
8995
- 哈希索引**只支持等值比较查询**,不支持任何范围查询,如 `WHERE price > 100`
9096
- 哈希索引有**可能出现哈希冲突**,出现哈希冲突时,必须遍历链表中所有的行指针,逐行比较,直到找到符合条件的行。
9197

92-
### B 树索引
98+
### 2.2. B 树索引
9399

94100
通常我们所说的索引是指`B-Tree`索引,它是目前关系型数据库中查找数据最为常用和有效的索引,大多数存储引擎都支持这种索引。使用`B-Tree`这个术语,是因为 MySQL 在`CREATE TABLE`或其它语句中使用了这个关键字,但实际上不同的存储引擎可能使用不同的数据结构,比如 InnoDB 就是使用的`B+Tree`
95101

@@ -141,25 +147,25 @@ B+ 树索引适用于**全键值查找**、**键值范围查找**和**键前缀
141147

142148
这时候我们就要优先考虑上一段提到的“尽量使用主键查询”原则,直接将这个索引设置为主键,可以避免每次查询需要搜索两棵树。
143149

144-
### 全文索引
150+
### 2.3. 全文索引
145151

146152
MyISAM 存储引擎支持全文索引,用于查找文本中的关键词,而不是直接比较是否相等。查找条件使用 MATCH AGAINST,而不是普通的 WHERE。
147153

148154
全文索引一般使用倒排索引实现,它记录着关键词到其所在文档的映射。
149155

150156
InnoDB 存储引擎在 MySQL 5.6.4 版本中也开始支持全文索引。
151157

152-
### 空间数据索引
158+
### 2.4. 空间数据索引
153159

154160
MyISAM 存储引擎支持空间数据索引(R-Tree),可以用于地理数据存储。空间数据索引会从所有维度来索引数据,可以有效地使用任意维度来进行组合查询。
155161

156162
必须使用 GIS 相关的函数来维护数据。
157163

158-
## 三、索引的类型
164+
## 3. 索引的类型
159165

160166
主流的关系型数据库一般都支持以下索引类型:
161167

162-
### 主键索引(`PRIMARY`
168+
### 3.1. 主键索引(`PRIMARY`
163169

164170
主键索引:一种特殊的唯一索引,不允许有空值。一个表只能有一个主键(在 InnoDB 中本质上即聚簇索引),一般是在建表的时候同时创建主键索引。
165171

@@ -171,7 +177,7 @@ CREATE TABLE `table` (
171177
)
172178
```
173179

174-
### 唯一索引(`UNIQUE`
180+
### 3.2. 唯一索引(`UNIQUE`
175181

176182
唯一索引:**索引列的值必须唯一,但允许有空值**。如果是组合索引,则列值的组合必须唯一。
177183

@@ -182,7 +188,7 @@ CREATE TABLE `table` (
182188
)
183189
```
184190

185-
### 普通索引(`INDEX`
191+
### 3.3. 普通索引(`INDEX`
186192

187193
普通索引:最基本的索引,没有任何限制。
188194

@@ -193,7 +199,7 @@ CREATE TABLE `table` (
193199
)
194200
```
195201

196-
### 全文索引(`FULLTEXT`
202+
### 3.4. 全文索引(`FULLTEXT`
197203

198204
全文索引:主要用来查找文本中的关键字,而不是直接与索引中的值相比较。
199205

@@ -207,7 +213,7 @@ CREATE TABLE `table` (
207213
)
208214
```
209215

210-
### 联合索引
216+
### 3.5. 联合索引
211217

212218
组合索引:多个字段上创建的索引,只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用。使用组合索引时遵循最左前缀集合。
213219

@@ -218,7 +224,7 @@ CREATE TABLE `table` (
218224
)
219225
```
220226

221-
## 四、索引的策略
227+
## 4. 索引的策略
222228

223229
假设有以下表:
224230

@@ -234,15 +240,15 @@ CREATE TABLE `t` (
234240
) ENGINE=InnoDB;
235241
```
236242

237-
### 索引基本原则
243+
### 4.1. 索引基本原则
238244

239245
- **索引不是越多越好,不要为所有列都创建索引**。要考虑到索引的维护代价、空间占用和查询时回表的代价。索引一定是按需创建的,并且要尽可能确保足够轻量。一旦创建了多字段的联合索引,我们要考虑尽可能利用索引本身完成数据查询,减少回表的成本。
240246
-**尽量避免冗余和重复索引**
241247
-**考虑删除未使用的索引**
242248
- **尽量的扩展索引,不要新建索引**
243249
- **频繁作为 `WHERE` 过滤条件的列应该考虑添加索引**
244250

245-
### 独立的列
251+
### 4.2. 独立的列
246252

247253
**“独立的列” 是指索引列不能是表达式的一部分,也不能是函数的参数**
248254

@@ -257,9 +263,9 @@ SELECT actor_id FROM actor WHERE actor_id + 1 = 5;
257263
SELECT ... WHERE TO_DAYS(current_date) - TO_DAYS(date_col) <= 10;
258264
```
259265

260-
### 覆盖索引
266+
### 4.3. 覆盖索引
261267

262-
**覆盖索引是指,索引上的信息足够满足查询请求,不需要再回到主键索引上去取数据**
268+
**覆盖索引是指,索引上的信息足够满足查询请求,不需要回表查询数据**
263269

264270
【示例】范围查询
265271

@@ -290,7 +296,7 @@ select * from T where k between 3 and 5
290296

291297
**由于覆盖索引可以减少树的搜索次数,显著提升查询性能,所以使用覆盖索引是一个常用的性能优化手段。**
292298

293-
### 使用索引来排序
299+
### 4.4. 使用索引来排序
294300

295301
Mysql 有两种方式可以生成排序结果:通过排序操作;或者按索引顺序扫描。
296302

@@ -302,7 +308,7 @@ Mysql 有两种方式可以生成排序结果:通过排序操作;或者按
302308
2. 从索引 (city,name,age) 取下一个记录,同样取出这三个字段的值,作为结果集的一部分直接返回;
303309
3. 重复执行步骤 2,直到查到第 1000 条记录,或者是不满足 city='杭州’条件时循环结束。
304310

305-
### 前缀索引
311+
### 4.5. 前缀索引
306312

307313
有时候需要索引很长的字符列,这会让索引变得大且慢。
308314

@@ -331,9 +337,11 @@ select
331337
from SUser;
332338
```
333339

334-
当然,使用前缀索引很可能会损失区分度,所以你需要预先设定一个可以接受的损失比例,比如 5%。然后,在返回的 L4~L7 中,找出不小于 L \* 95% 的值,假设这里 L6、L7 都满足,你就可以选择前缀长度为 6。
340+
当然,**使用前缀索引很可能会损失区分度**,所以你需要预先设定一个可以接受的损失比例,比如 5%。然后,在返回的 L4~L7 中,找出不小于 L \* 95% 的值,假设这里 L6、L7 都满足,你就可以选择前缀长度为 6。
335341

336-
### 最左前缀匹配原则
342+
此外,**`order by` 无法使用前缀索引,无法把前缀索引用作覆盖索引**
343+
344+
### 4.6. 最左前缀匹配原则
337345

338346
不只是索引的全部定义,只要满足最左前缀,就可以利用索引来加速检索。这个最左前缀可以是联合索引的最左 N 个字段,也可以是字符串索引的最左 M 个字符。
339347

@@ -366,19 +374,19 @@ customer_id_selectivity: 0.0373
366374
COUNT(*): 16049
367375
```
368376

369-
### = 和 in 可以乱序
377+
### 4.7. = 和 in 可以乱序
370378

371379
**不需要考虑 `=``IN` 等的顺序**,Mysql 会自动优化这些条件的顺序,以匹配尽可能多的索引列。
372380

373381
【示例】如有索引 (a, b, c, d),查询条件 `c > 3 and b = 2 and a = 1 and d < 4``a = 1 and c > 3 and b = 2 and d < 4` 等顺序都是可以的,MySQL 会自动优化为 a = 1 and b = 2 and c > 3 and d < 4,依次命中 a、b、c、d。
374382

375-
## 五、索引最佳实践
383+
## 5. 索引最佳实践
376384

377385
创建了索引,并非一定有效。比如不满足前缀索引、最左前缀匹配原则、查询条件涉及函数计算等情况都无法使用索引。此外,即使 SQL 本身符合索引的使用条件,MySQL 也会通过评估各种查询方式的代价,来决定是否走索引,以及走哪个索引。
378386

379387
因此,在尝试通过索引进行 SQL 性能优化的时候,务必通过执行计划(`EXPLAIN`)或实际的效果来确认索引是否能有效改善性能问题,否则增加了索引不但没解决性能问题,还增加了数据库增删改的负担。如果对 EXPLAIN 给出的执行计划有疑问的话,你还可以利用 `optimizer_trace` 查看详细的执行计划做进一步分析。
380388

381-
## 参考资料
389+
## 6. 参考资料
382390

383391
- [《高性能 MySQL》](https://book.douban.com/subject/23008813/)
384392
- [数据库两大神器【索引和锁】](https://juejin.im/post/5b55b842f265da0f9e589e79)

0 commit comments

Comments
 (0)