本系列主要是针对<高性能MySQL>原著进行内容抽取,帮助开发者快速阅读书籍
第一章 MySQL架构与历史
一.锁机制
1.读写锁
- 1.1 读锁(共享锁):多个用户在同一时刻可以同时读取同一个资源,而且互不干扰
- 1.2 写锁(排他锁):一个写锁会阻塞其他的写锁和读锁.出于安全考虑,在给定时间中,只有一个用户能够执行写入,并防止其他用户产生脏读
2.锁的粒度
- 2.1 表级锁:一个用户在进行DQL的时候,表将被锁定
- 2.2 行级锁:用于对但张表的批量DQL产生
二.事务
1.特性
- 原子性(Atomicity):操作不可分割
- 一致性(Consistency):操作前后数据总量不会改变
- 隔离性(Isolation):事务之间互不干扰
- 持久性(Durability):操作将永久改变
2.没有事务将产生的问题
- 2.1 脏读:读取了其它操作中未提交的数据
- 2.2 不可重复读:两次查询结果不一致,由于更新导致
- 2.3 幻读:两次查询结果不一致,由于新增或者删除导致
3.MySQL的隔离级别
- Serializable (串行化):可避免脏读、不可重复读、幻读的发生
- Repeatable read (可重复读):可避免脏读、不可重复读的发生。
- Read committed (读已提交):可避免脏读的发生。
- Read uncommitted (读未提交):最低级别,任何情况都无法保证。
MySQL默认为Repeatable read
4.死锁
当两个或者多个UPDATE语句要同时执行时产生死锁,解决方案是让持有最少写锁的事务回滚,释放锁后即可重新执行
三.存储引擎
1.MyISAM
- 不支持事务,但是整个操作是原子性的
- 不支持外键,支持表锁
- 一个MyISAM表有三个文件:索引文件,表结构文件,数据文件
- 自动存储表的总行数,执行select count(*) from table时只要简单的读出保存好的行数即可
- 采用非聚集索引,索引文件的数据域存储指向数据文件的指针。辅索引与主索引基本一致,但是辅索引不用保证唯一性。
- 支持全文索引和空间索引
2.InnoDB
- 支持事务
- 支持行锁和外键约束,因此可以支持写并发
- 不存储总行数,执行select count(*) from table效率比MyISAM低
- 对于AUTO_INCREMENT类型的字段,InnoDB中必须包含只有该字段的索引.即是选定自动增长的健必定作为索引
- 一个Innodb表存储在一个文件内(共享表空间,表大小不受操作系统的限制),也可能为多个(设置为独立表空间,表大小受操作系统限制,大小为2G),受操作系统文件大小的限制
MyISAM引擎的表分成三个文件存储数据,但是InnoDB可以只存储在一个文件内,也可以存储在多个文件内
- 主键索引采用聚集索引(索引的数据域存储数据文件本身),辅索引的数据域存储主键的值;因此从辅索引查找数据,需要先通过辅索引找到主键值,再访问主键索引;最好使用自增主键,防止插入数据时,为维持B+树结构,文件的大调整。
总结:MySQL还有其它很多的存储引擎,然而那些都没啥用处.大部分情况下InnoDB都是正确选择,除非需要使用到它不具备的特性
第二章 MySQL的基准测试
测试流程和测试工具推荐一位写的不错的博客,古寨城主.对于普通开发者而言,跟着该步骤操作一下即可,不建议十分深入
第三章 服务器性能剖析
- 1.定义性能最有效的是响应时间
- 2.性能优化的前提是进行响应时间的测量
- 3.测量的开始点是应用程序,而不是数据库
- 4.响应时间可以分成执行时间和等待时间,性能优化需要从这两点入手
- 5.优化和提升是两回事,当继续提升的成本已经超过收益,应当立即停止优化
第四章 Schema与数据类型优化
一.数据类型的优化
1.数据类型的选择
- 存储数据的类型磁盘占用越小越好
- 避免使用NULL,通常情况下选择为NOT NULL,因为NULL的列会使用更多的存储空间
- CHAR和VARCHAR,优先选择CHAR,VARCHAR需要使用1或者2个额外字节记录字符串长度是可变字符串,CHAR是定长的.所以使用CHAR性能更佳
- 时间范围在1970年~2038年之间,选用TIMESTAMP,除此之外选择DATETIME
- IPV4使用int UNSIGNED存储,不要使用传统的VARCHAR(15),int只占4个字节,VARCHAR占用了15个字节.常见于登录日志.当日志表数据量一大,那就将是一个巨大的区别
2.范式和反范式
范式:数据库规范的手段,避免冗余数据的存放
- 第一范式:数据库每一列只能存放单一值
- 第二范式:所有数据都要和该数据表的主键有完全相依的关系
- 第三范式:要求非键属性之间应该是没有关系的
优点:使编程相对简单,数据量更小,更适合放入内存,更新更快,
缺点:查询更复杂
反范式:
试图增加冗余数据或分组数据来优化数据库读取性能的过程,减少了表之间的连接
但如果冗余数据量过大的时候,可能会碰到I/O瓶颈,导致性能变得更差,所以需要
衡量各个表的更新量和查询量
在数据统计分析,数据仓库等领域使用的比较多
3.缓存表,汇总表,计数器表
- 缓存表:临时数据的存放,例如是否登录过期的token校验
- 汇总表:对于一些查询很慢的数据,通过汇总记录到汇总表当中
- 计数器表:对于用户朋友数,访问量,下载量等信息可以作为一个单独表存储,可以避免查询缓存失效
4.附录:
- 4.1 避免使用MySQL已经遗弃的特性,例如浮点数的精度,或者整数的显示宽度
- 4.2 尽量使用整型定义标识列