@@ -15,39 +15,41 @@ tags:
15
15
- [ 1. 存储引擎] ( #1-存储引擎 )
16
16
- [ 1.1. InnoDB] ( #11-innodb )
17
17
- [ 1.2. MyISAM] ( #12-myisam )
18
- - [ 1.3. 比较 ] ( #13-比较 )
18
+ - [ 1.3. 选择存储引擎 ] ( #13-选择存储引擎 )
19
19
- [ 2. 数据类型] ( #2-数据类型 )
20
20
- [ 2.1. 整型] ( #21-整型 )
21
21
- [ 2.2. 浮点数] ( #22-浮点数 )
22
22
- [ 2.3. 字符串] ( #23-字符串 )
23
23
- [ 2.4. 时间和日期] ( #24-时间和日期 )
24
24
- [ 3. 事务] ( #3-事务 )
25
- - [ 事务隔离级别] ( #事务隔离级别 )
26
- - [ 死锁] ( #死锁 )
27
- - [ MVCC] ( #mvcc )
28
- - [ 4 . 索引] ( #4 -索引 )
29
- - [ 4 .1. 索引的优点和缺点] ( #41 -索引的优点和缺点 )
30
- - [ 4 .2. 索引类型] ( #42 -索引类型 )
31
- - [ 4 .3. 索引数据结构] ( #43 -索引数据结构 )
32
- - [ 4 .4. 索引原则] ( #44 -索引原则 )
33
- - [ 5 . 查询性能优化] ( #5 -查询性能优化 )
34
- - [ 5 .1. 使用 Explain 进行分析] ( #51 -使用-explain-进行分析 )
35
- - [ 5 .2. 优化数据访问] ( #52 -优化数据访问 )
36
- - [ 5 .3. 重构查询方式] ( #53 -重构查询方式 )
37
- - [ 6 . 复制] ( #6 -复制 )
38
- - [ 6 .1. 主从复制] ( #61 -主从复制 )
39
- - [ 6 .2. 读写分离] ( #62 -读写分离 )
40
- - [ 7 . 参考资料] ( #7 -参考资料 )
25
+ - [ 3.1. 事务隔离级别] ( #31- 事务隔离级别 )
26
+ - [ 3.2. 死锁] ( #32- 死锁 )
27
+ - [ 4. MVCC] ( #4- mvcc )
28
+ - [ 5 . 索引] ( #5 -索引 )
29
+ - [ 5 .1. 索引的优点和缺点] ( #51 -索引的优点和缺点 )
30
+ - [ 5 .2. 索引类型] ( #52 -索引类型 )
31
+ - [ 5 .3. 索引数据结构] ( #53 -索引数据结构 )
32
+ - [ 5 .4. 索引原则] ( #54 -索引原则 )
33
+ - [ 6 . 查询性能优化] ( #6 -查询性能优化 )
34
+ - [ 6 .1. 使用 Explain 进行分析] ( #61 -使用-explain-进行分析 )
35
+ - [ 6 .2. 优化数据访问] ( #62 -优化数据访问 )
36
+ - [ 6 .3. 重构查询方式] ( #63 -重构查询方式 )
37
+ - [ 7 . 复制] ( #7 -复制 )
38
+ - [ 7 .1. 主从复制] ( #71 -主从复制 )
39
+ - [ 7 .2. 读写分离] ( #72 -读写分离 )
40
+ - [ 8 . 参考资料] ( #8 -参考资料 )
41
41
42
42
<!-- /TOC -->
43
43
44
44
## 1. 存储引擎
45
45
46
+ 在文件系统中,Mysql 将每个数据库(也可以成为 schema)保存为数据目录下的一个子目录。创建表示,Mysql 会在数据库子目录下创建一个和表同名的 .frm 文件保存表的定义。因为 Mysql 使用文件系统的目录和文件来保存数据库和表的定义,大小写敏感性和具体平台密切相关。Windows 中大小写不敏感;类 Unix 中大小写敏感。** 不同的存储引擎保存数据和索引的方式是不同的,但表的定义则是在 Mysql 服务层统一处理的。**
47
+
46
48
### 1.1. InnoDB
47
49
48
50
InnoDB 是 MySQL 默认的事务型存储引擎,只有在需要 InnoDB 不支持的特性时,才考虑使用其它存储引擎。
49
51
50
- 实现了四个标准的隔离级别,默认级别是可重复读(REPEATABLE READ)。在可重复读隔离级别下,通过多版本并发控制(MVCC)+ 间隙锁(next-key locking)防止幻影读。
52
+ InnoDB 实现了四个标准的隔离级别,默认级别是可重复读(REPEATABLE READ)。在可重复读隔离级别下,通过多版本并发控制(MVCC)+ 间隙锁(next-key locking)防止幻影读。
51
53
52
54
主索引是聚簇索引,在索引中保存了数据,从而避免直接读取磁盘,因此对查询性能有很大的提升。
53
55
@@ -69,15 +71,37 @@ MyISAM 提供了大量的特性,包括压缩表、空间数据索引等。
69
71
70
72
如果指定了 DELAY_KEY_WRITE 选项,在每次修改执行完成时,不会立即将修改的索引数据写入磁盘,而是会写到内存中的键缓冲区,只有在清理键缓冲区或者关闭表的时候才会将对应的索引块写入磁盘。这种方式可以极大的提升写入性能,但是在数据库或者主机崩溃时会造成索引损坏,需要执行修复操作。
71
73
72
- ### 1.3. 比较
74
+ ### 1.3. 选择存储引擎
75
+
76
+ #### Mysql 内置的存储引擎
77
+
78
+ - ** InnoDB** - Mysql 的默认事务型存储引擎。性能不错且支持自动崩溃恢复。
79
+ - ** MyISAM** - Mysql 5.1 版本前的默认存储引擎。特性丰富但不支持事务,也没有崩溃恢复功能。
80
+ - ** CSV** - 可以将 CSV 文件作为 Mysql 的表来处理,但这种表不支持索引。
81
+ - ** Memory** - 适合快速访问数据,且数据不会被修改,重启丢失也没有关系。
82
+ - ** NDB** - 用于 Mysql 集群场景。
83
+
84
+ #### 如何选择合适的存储引擎?
85
+
86
+ 大多数情况下,InnoDB 都是正确的选择,除非需要用到 InnoDB 不具备的特性。
87
+
88
+ 如果应用需要选择 InnoDB 以外的存储引擎,可以考虑以下因素:
73
89
74
- - 事务:InnoDB 是事务型的,可以使用 Commit 和 Rollback 语句 。
75
- - 并发:MyISAM 只支持表级锁,而 InnoDB 还支持行级锁。
90
+ - 事务:如果需要支持事务, InnoDB 是首选。如果不需要支持事务,且主要是 SELECT 和 INSERT 操作,MyISAM 是不错的选择 。
91
+ - 并发:MyISAM 只支持表级锁,而 InnoDB 还支持行级锁。所以,InnoDB 并发性能更高。
76
92
- 外键:InnoDB 支持外键。
77
93
- 备份:InnoDB 支持在线热备份。
78
94
- 崩溃恢复:MyISAM 崩溃后发生损坏的概率比 InnoDB 高很多,而且恢复的速度也更慢。
79
95
- 其它特性:MyISAM 支持压缩表和空间数据索引。
80
96
97
+ #### 转换表的存储引擎
98
+
99
+ 下面的语句可以将 mytable 表的引擎修改为 InnoDB
100
+
101
+ ``` sql
102
+ ALTER TABLE mytable ENGINE = InnoDB;
103
+ ```
104
+
81
105
## 2. 数据类型
82
106
83
107
### 2.1. 整型
@@ -136,17 +160,17 @@ Mysql 不是所有的存储引擎都实现了事务处理。支持事务的存
136
160
137
161
Mysql 默认采用自动提交(AUTOCOMMIT)模式。
138
162
139
- ### 事务隔离级别
163
+ ### 3.1. 事务隔离级别
140
164
141
165
InnoDB 支持 SQL 标准的四种隔离级别,默认的级别是可重复读。并且,通过间隙锁(next-key locking)策略防止幻读的出现。
142
166
143
- ### 死锁
167
+ ### 3.2. 死锁
144
168
145
169
在 Mysql 中,锁的行为和顺序与存储引擎相关。
146
170
147
171
InnoDB 中解决死锁问题的方法是:将持有最少行级排他锁的事务进行回滚。
148
172
149
- ## MVCC
173
+ ## 4. MVCC
150
174
151
175
InnoDB 的 MVCC,是通过在每行记录后面保存两个隐藏的列来实现的。这两个列,一个保存了行的创建时间,一个保存行的过期时间。当然,存储的并不是实际的时间值,而是系统版本号。每开始一个新事务,系统版本号就会自动递增。事务开始时的系统版本号会作为事务的版本号,用来和查询到的每行记录的版本号进行比较。
152
176
@@ -174,15 +198,15 @@ InnoDB 的 MVCC,是通过在每行记录后面保存两个隐藏的列来实
174
198
175
199
将当前系统版本号作为更新后的数据行快照的创建版本号,同时将当前系统版本号作为更新前的数据行快照的删除版本号。可以理解为先执行 DELETE 后执行 INSERT。
176
200
177
- ## 4 . 索引
201
+ ## 5 . 索引
178
202
179
203
索引能够轻易将查询性能提升几个数量级。
180
204
181
205
对于非常小的表、大部分情况下简单的全表扫描比建立索引更高效。对于中到大型的表,索引就非常有效。但是对于特大型的表,建立和维护索引的代价将会随之增长。这种情况下,需要用到一种技术可以直接区分出需要查询的一组数据,而不是一条记录一条记录地匹配,例如可以使用分区技术。
182
206
183
207
索引是在存储引擎层实现的,而不是在服务器层实现的,所以不同存储引擎具有不同的索引类型和实现。
184
208
185
- ### 4 .1. 索引的优点和缺点
209
+ ### 5 .1. 索引的优点和缺点
186
210
187
211
优点:
188
212
@@ -196,7 +220,7 @@ InnoDB 的 MVCC,是通过在每行记录后面保存两个隐藏的列来实
196
220
2 . 索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立组合索引那么需要的空间就会更大。
197
221
3 . 当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。
198
222
199
- ### 4 .2. 索引类型
223
+ ### 5 .2. 索引类型
200
224
201
225
MySQL 目前主要有以下几种索引类型:
202
226
@@ -257,7 +281,7 @@ CREATE TABLE `table` (
257
281
)
258
282
```
259
283
260
- ### 4 .3. 索引数据结构
284
+ ### 5 .3. 索引数据结构
261
285
262
286
#### B+Tree 索引
263
287
@@ -366,7 +390,7 @@ MyISAM 存储引擎支持空间数据索引,可以用于地理数据存储。
366
390
367
391
必须使用 GIS 相关的函数来维护数据。
368
392
369
- ### 4 .4. 索引原则
393
+ ### 5 .4. 索引原则
370
394
371
395
#### 最左前缀匹配原则
372
396
@@ -434,9 +458,9 @@ WhERE actor_id = 1 AND film_id = 1;
434
458
- 一些存储引擎(例如 MyISAM)在内存中只缓存索引,而数据依赖于操作系统来缓存。因此,只访问索引可以不使用系统调用(通常比较费时)。
435
459
- 对于 InnoDB 引擎,若辅助索引能够覆盖查询,则无需访问主索引。
436
460
437
- ## 5 . 查询性能优化
461
+ ## 6 . 查询性能优化
438
462
439
- ### 5 .1. 使用 Explain 进行分析
463
+ ### 6 .1. 使用 Explain 进行分析
440
464
441
465
Explain 用来分析 SELECT 查询语句,开发人员可以通过分析 Explain 结果来优化查询语句。
442
466
@@ -448,7 +472,7 @@ Explain 用来分析 SELECT 查询语句,开发人员可以通过分析 Explai
448
472
449
473
更多内容请参考:[ MySQL 性能优化神器 Explain 使用分析] ( https://segmentfault.com/a/1190000008131735 )
450
474
451
- ### 5 .2. 优化数据访问
475
+ ### 6 .2. 优化数据访问
452
476
453
477
#### 减少请求的数据量
454
478
@@ -468,7 +492,7 @@ Explain 用来分析 SELECT 查询语句,开发人员可以通过分析 Explai
468
492
469
493
最有效的方式是使用索引来覆盖查询。
470
494
471
- ### 5 .3. 重构查询方式
495
+ ### 6 .3. 重构查询方式
472
496
473
497
#### 切分大查询
474
498
@@ -509,9 +533,9 @@ SELECT * FROM tag_post WHERE tag_id=1234;
509
533
SELECT * FROM post WHERE post.id IN (123,456,567,9098,8904);
510
534
```
511
535
512
- ## 6 . 复制
536
+ ## 7 . 复制
513
537
514
- ### 6 .1. 主从复制
538
+ ### 7 .1. 主从复制
515
539
516
540
主要涉及三个线程:binlog 线程、I/O 线程和 SQL 线程。
517
541
@@ -523,7 +547,7 @@ SELECT * FROM post WHERE post.id IN (123,456,567,9098,8904);
523
547
<img src =" https://raw.githubusercontent.com/dunwu/Database/master/images/mysql/master-slave.png " />
524
548
</div >
525
549
526
- ### 6 .2. 读写分离
550
+ ### 7 .2. 读写分离
527
551
528
552
主服务器用来处理写操作以及实时性要求比较高的读操作,而从服务器用来处理读操作。
529
553
@@ -539,7 +563,7 @@ MySQL 读写分离能提高性能的原因在于:
539
563
<img src =" https://raw.githubusercontent.com/dunwu/Database/master/images/mysql/master-slave-proxy.png " />
540
564
</div >
541
565
542
- ## 7 . 参考资料
566
+ ## 8 . 参考资料
543
567
544
568
- BaronScbwartz, PeterZaitsev, VadimTkacbenko 等. 高性能 MySQL[ M] . 电子工业出版社, 2013.
545
569
- 姜承尧. MySQL 技术内幕: InnoDB 存储引擎 [ M] . 机械工业出版社, 2011.
0 commit comments