高性能MySQL
第一章 mysql架构及历史
每个客户端连接在服务端进程中拥有一个独立的线程,该客户端的查询会在该线程中执行。线程会缓存在服务端,因此无需将每个新建连接创建线程,直接从缓存中获取。
当客户端连接到服务端时,首先需要进行用户密码验证,验证通过后,还要验证每个查询的操作权限。
读写锁
读锁是共享锁,即多个读操作可以同时进行用户。写锁是排他锁,即进行写操作时,其他读或写操作会被阻塞。
表级锁是开销最小的锁策略。行级锁是开销最大的锁策略,同时最大程度的支持并发。
事务(ACID)
A代表Atomicity,即原子性。C代表Consistancy,即一致性。I代表Isolation,即隔离性。D代表Duration,即持久性。
隔离级别
read uncommited(未提交读),一个事务可以读取另一个事务没有提交的数据,可能导致脏读。
read commited(提交读),大部分数据库默认的隔离级别,可能导致不可重复读。
repeatable read(可重复读),mysql默认隔离级别,可能导致幻读。
serelizable(序列化),隔离级别最高,但性能也最差,一般不会使用。
死锁
两个及以上事务相互占用对方请求的资源。为了解决死锁问题,数据库系统引入了死锁检测和死锁超时机制。如果发生了死锁,只有部分或全部回滚其中一个事务,才能解决死锁问题。
事务日志
事务日志可以提高事务的效率。修改数据时,先将修改的数据写入内存拷贝中,再以追加的方式将事务日志写入到磁盘的日志中(追加是顺序IO,比随机IO性能高)。然后慢慢将内存的修改数据刷回到磁盘。称为预写式日志(Write-Ahead-Logging)。
innodb是支持事务的存储引擎,myisam属于非事务存储引擎。innodb采用autocommit(自动提交)模式,即每个查询如果没有显式开启事务,会自动commit或rollback。可以通过设置AUTOCOMMIT属性为False或0,来禁止自动提交。
显示锁定语句
SELECT...LOCK IN SHARE MODE
SELECT... FOR UPDATE
MVCC(多版本并发控制)
为了提高并发性能,大多数Mysql的事务型存储引擎都实现了 MVCC。INNODB的MVCC是通过每行增加两个隐藏的列(创建版本号和删除版本号)。每新增一个事务,系统版本号自动递增。事务开始时以当前系统版本号作为事务版本号。以下通过SELECT、INSERT、DELETE、UPDATE具体说明:
SELECT操作,INNODB返回行版本号小于或等于当前事务版本号,并且行删除版本号不存在或大于当前事务版本号的行。
INSERT操作,INNODB插入行保存当前系统版本号作为行版本号。
DELETE操作,INNODB删除行保存当前系统版本号作为删除版本号。
UPDATE操作,INNODB新增行保存当前系统版本号作为行版本号,删除行保存当前系统版本号作为删除版本号。
MVCC只在REPEATABLE READ和READ COMMITED两种隔离级别下有效。
第四章 数据类型
更小和更简单的数据类型通常代表更好,因为需要的磁盘、内存、CPU缓存更少,甚至需要的CPU周期更低。
时间类型有两种:timestamp和datetime。timestamp需要的存储空间只有datetime的一半,而且可以根据时区自动变更,代价是可用范围很小。
整型包括:tinyint(8位),smallint(16位),mediumint(24位),int(32位),bigint(64位)。
实数包括浮点型的float和double以及用于高精度计算的decimal。
常用字符类型包括varchar和char。其中varchar用于存储空间可变的字符,只使用必要的存储空间,如果存储的字节小于等于255,需要1个字节的额外长度,大于255需要2个字节,varchar在存储和检索时不会截断末尾空格。char用于存储空间不变且长度较小的字符,不足位用空格填充,char会截断末尾空格。
第五章 索引
索引是存储引擎用于快速查找数据记录的一种数据结构。对查询性能优化非常关键。索引是在存储引擎层实现的。
B-Tree结构索引
MyISAM索引的叶子节点指向被引用数据的物理位置,INNODB索引的叶子节点指向引用数据的主键。INNODB使用B+TREE,支持的特性包括:全值匹配,范围查找和最左列前缀查找。
索引的优点:
1、帮助服务器减少需要扫描的数据量
2、帮助服务器避免排序和临时表
3、帮助服务器将随机IO变成顺序IO
覆盖索引
是指数据结构中包含了BTREE索引和数据行。INNODB的覆盖索引默认是通过主键,如果没有主键则以唯一的非空列作为覆盖索引,如果都没有则生成隐形的主键作为覆盖索引,数据行存储在叶节点。二级索引的叶节点储存了主键列值。
索引和锁
INNODB只会对访问行加锁,而索引可以减少访问行,从而减少锁的数量。