Skip to content

Commit 314b9a3

Browse files
authored
Update 高性能MySQL.md
1 parent 1d1fa8e commit 314b9a3

File tree

1 file changed

+59
-3
lines changed

1 file changed

+59
-3
lines changed

docs/2019/高性能MySQL.md

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
55
假设数据库中国一张邮箱表,每个邮件都是一条记录。如果某个客户正在读取邮箱,同时其他客户试图在删除邮箱表中的某一条数据。这个时候,读取的结构就是不确定的了。在MySql中会通过锁定防止其它用户读取同一数据。大多数时候,MySQL锁的内部管理都是透明的。
66

7-
## MySQL锁的粒度
7+
# MySQL锁的粒度
88
* 每种MySql引擎都可以实现自己的锁策略和锁粒度,将锁粒度固定在某个级别,可以为某些特定的场景提供更好的性能。
99

1010
**表锁(table lock)**
@@ -21,7 +21,7 @@
2121
*`InnoDB``XtraDB`,以及其他一些存储引擎中实现了行级锁。
2222
* 行级锁只在存储引擎层实现,而MySQL服务器层没有实现。服务器层完全不了解存储引擎中的锁实现。
2323

24-
## MySQL的事务
24+
# MySQL的事务
2525
**事务特性**
2626
* A(原子性)事务的各步操作是不可分的,保证一系列的操作要么都完成,要么都不完成;
2727
* C(一致性)事务完成,数据必须处于一致的状态;
@@ -44,7 +44,7 @@
4444
锁是在同一时刻被释放。
4545
* InnoDB也支持通过特定的语句进行显式锁定`SELECT ... LOCK IN SHARE MODE``SELECT FOR UPDATE` 些语句不属于SQL规范
4646

47-
## 多版本并发控制MVCC
47+
# 多版本并发控制MVCC
4848
* `MVCC`是行级锁的一个变种,但是它在很多情况下避免了加锁操作,因此开销更低。虽然实现机制有所不同,但大都实现了非阻塞的读操作,写操作也只锁定必要的行。
4949
* MVCC的实现,是通过保存数据在某个时间点的快照来实现的。也就是说,不管需要执行多长时间,每个事务看到的数据都是一致的。根据事务开始的时间不同,每个事务对同张表,同一时刻看到的数据可能是不一样的。
5050
* `InnoDB`的MVCC,是通过在每行记录后面保存两个隐藏的列来实现的。这两个列,一个保存了行的创建时间,一个保存行的过期时间(或删除时间)。当然存储的并不是实际的时间值,而是系统版本号。每开始一个新的事务,系统版本号都会自动递增。事务开始时刻的系统版本号会作为事务的版本号,用来和查询到的每行记录的版本号进行比较。
@@ -67,3 +67,59 @@ InnoDB会根据以下两个条件检查每行记录:
6767
**UPDATE**
6868
* InnoDB为插入-行新记录,保存当前系统版本号作为行版本号,同时保存当前系统
6969
版本号到原来的行作为行删除标识。
70+
71+
# 数据库存储引擎
72+
## InnDB存储引擎
73+
* InnDB是Mysql默认的事务型存储引擎。它被设计用来处理大量的短期(short-lived) 事务,短期事务大部分情况是正常提交的,很少会被回滚。InnoDB的性能和自动崩溃恢复特性,使得它在非事务型存储的需求中也很流行
74+
* InnoDB的数据存储在表空间(tablespace) 中,表空间是由InnoDB管理的-个黑盒子,由一系列的数据文件组成。
75+
* InnoDB采用`MVCC`来支持高并发,并且实现了四个标准的隔离级别。其默认级别是
76+
REPEATABLE READ (`可重复读`) ,并且通过`间隙锁`(next-key locking)策略防止`幻读`的出现。间隙锁使得InnoDB不仅仅锁定查询涉及的行,还会对索引中的间隙进行锁定,以防止幻影行的插入。
77+
* InnoDB表是基于聚簇索引建立的。聚簇素引对主键查询有很高的性能,不过它的二级索引(secondary index,非主键索引)中必须包含主键列,所以如果主键列很大的话,其他的所有索引都会很大。因此,若表上的索引较多的话,主键应当尽可能的小。
78+
* InnoDB内部做了很多优化,包括从磁盘读取数据时采用的可预测性预读,能够自动在
79+
内存中创建hash索引以加速读操作的自适应哈希索引(adaptive hash index),以及能够
80+
加速插入操作的插入缓冲区(insert buffer)等
81+
82+
## MyISAM引擎
83+
* `MyISAM不支持事务和行锁`,在MySQL5.1之前的版本是默认的存储引擎,有一个缺陷是崩溃后无法恢复。
84+
* 优点是对于只读的数据,或者表比较小,可以忍受修复操作,可以继续使用
85+
* MyISAM会将表存储在两个文件中:数据文件和索引文件,分别以.MYD和.MYI为扩展名
86+
* MyISAM表可以包含动态或者静态(长度固定)行。MySQL会根据表的定义来决定采用何种行格式。MyISAM表可以存储的行记录数,一般受限于可用的磁盘空间,或者操作系统中单个文件的最大尺寸。
87+
* `MyISAM对整张表加锁,而不是针对行`。读取时会对需要读到的所有表加共享锁,写入时则对表加排他锁。但是在表有读取查询的同时,也可以往表中插入新的记录(这被称为并发插入)
88+
89+
## Archive引擎
90+
* Archive引擎会缓存所有的写并利用zlib对插人的行进行压缩,所以比MyISAM表的磁盘I/O更少。但是每次SELECT查询都需要执行全表扫描。所以Archive表适合日志和数据采集类应用,这类应用做数据分析时往往需要全表扫描。或者在一- 些需要更快速的INSERT操作的场合下也可以使用。
91+
* `Archive引擎`支持`行级锁和专用的缓冲区`,所以可以实现高并发的插人。在一个查询开始直到返回表中存在的所有行数之前,Archive引擎会阻止其他的SELECT执行,以实现一致性读。另外,也实现了批量插入在完成之前对读操作是不可见的。这种机制模仿了事务和MVCC的一些特性,但Archive引擎不是一个事务型的引擎,而是-一个针对高速插人和压缩做了优化的简单引擎。
92+
93+
## Blackhole引擎
94+
* Blackhole引擎没有实现任何的存储机制,它会丟弃所有插入的数据,不做任何保存。但是服务器会记录Blackhole表的日志,所以可以用于复制数据到备库,或者只是简单地记录到日志。这种特殊的存储引擎可以在--些特殊的复制架构和8志审核时发挥作用。但这种应用方式我们碰到过很多问题,因此并不推荐。
95+
96+
## CSV引擎
97+
* CSV引擎可以将普通的CSV文件(逗号分割值的文件)作为MySQL的表来处理,但这种表不支持索引。CSV引擎可以在数据库运行时拷入或者拷出文件。可以将Excel等电子表格软件中的数据存储为CSV文件,然后复制到MySQL数据目录下,就能在MySQL中打开使用。同样,如果将数据写人到一个CSV引擎表,其他的外部程序也能立即从表的数据文件中读取CSV格式的数据。因此CSV引擎可以作为- -种数据交换的机制,非常有用。
98+
99+
## Federated引擎
100+
* Federated引擎是访问其他MySQL服务器的-一个代理,它会创建-一个到远程MySQL服务器的客户端连接,并将查询传输到远程服务器执行,然后提取或者发送需要的数据。最初设计该存储引擎是为了和企业级数据库如Microsoft SQL Server和Oracle的类似特性竞争的,可以说更多的是一种市场行为。尽管该引擎看起来提供了一种很好的跨服务器的灵活性,但也经常带来问题,因此默认是禁用的。
101+
102+
## Memory引擎
103+
* 如果需要快速地访问数据,并且这些数据不会被修改,重启以后丢失也没有关系,那么使用Memory表(以前也叫做HEAP表)是非常有用的。Memory 表至少比MyISAM表要快一个数量级,因为所有的数据都保存在内存中,不需要进行磁盘I/O。Memory 表的结构在重启以后还会保留,但数据会丢失。
104+
105+
106+
# Schema(数据库的组织和结构)与数据类型优化
107+
## 更小的通常好
108+
* 尽量使用可以正确存储数据的最下数据类型,更小的数据类型通常更快,占用更小的磁盘,内存和cpu缓存,并且处理时需要的cpu周期更少
109+
* 但是要确保没有低估需要存储的值的范围,因为在schema中的多个地方增加数据类型的范围是一个非常耗时和痛苦的操作。如果无法确定哪个数据类型是最好的,就选择你认为不会超过范围的最小类型
110+
111+
## 简单就好
112+
* 简单数据类型的操作通常需要更少的CPU周期。例如,整型比字符操作代价更低,
113+
* 整型比字符操作代价更低,因为字符集和校对规则(排序规则)使字符比较比整型比较更复杂
114+
* 使用MySQL内建的类型而不是字符串来存储日期和时间
115+
* 用整型存储IP地址
116+
117+
## 尽量避免NUll
118+
* 如果查询中包含null的列,会使得索引,索引统计和值比较更复杂
119+
* 当可以NULL的列被索引时,每个索引记录需要一个额外的字节
120+
121+
## datetime和timesamp
122+
* datetime和timesamp都可以存储相同的数据类型,时间和日期,精确到秒。然而timesamp只使用datetime一半的存储空间
123+
* timesamp 会根据时区变化,具有特殊的自动更新能力,允许的时间范围要小很多,有时它的特许能力会成为障碍
124+
125+

0 commit comments

Comments
 (0)