MySQL
基本架构
类似一个后端的服务器,数据库会事先开好线程并缓存这些线程,一条语句过来,数据库就会开启一个线程去处理,先去查询缓存中找,解析器中也会有相应的缓存,解析优化完后就通过 API 请求存储引擎
并发控制
读写锁
- 共享锁
- 排他锁
- 读锁
- 写锁
表锁,行级锁
事务
对于不需要事务的查询类应用,选择非事务型的存储引擎可以获得更高的性能
隔离级别
脏读:事务中的修改即使没有提交也对其他事务可见可读
可重复读
该级别保证同一事务中多次读取同样记录的结果是一致的
死锁
两个或多个事务在同一资源上相互占用 解决方式:设置锁等待超时,将持有最少行级排他锁的事务进行回滚
AUTOCOMMIT
默认采用自动提交,每个查询都被当做一个事务执行提交操作
存储引擎
MyISAM 存储引擎
5.1 版本以前,是默认的存储引擎,但是不支持事务和行级锁,崩溃后无法安全恢复 使用表锁,对性能影响很大 不修改的表可以使用压缩表极大节省磁盘空间 将表分别存储在数据文件和索引文件中 只读或者大部分只读的表可以使用这个存储引擎
InnoDB
使用文件系统的目录和文件保存数据库和表的定义 使用聚簇索引,对查询主键有很高的性能 从磁盘读取使用可预测性预读 加速读操作的自适应哈希索引
InnoDB VS MyISAM
两种类型最主要的差别就是 Innodb 支持事务处理与外键和行级锁
范式与反范式
范式化的数据库中,每个事实数据只会出现一次,无冗余 反范式的数据库中,信息是冗余的
使用范式的优点:
- 更新操作快,修改只需要修改少量数据
- 表通常更小,可以放在内存里
- 更少需要 DISTINCT 或 GROUP BY 语句 缺点:需要联表,可能使一些索引无效
反范式的优点:不需要关联表,避免了随机IO,即便是最坏情况需要全表扫描,也基本上是顺序IO 缺点:修改麻烦,数据冗余
混用范式与反范式
复制和缓存就是反范式的一个应用,使用触发器更新缓存值 缓存表和汇总表做一些定时统计也比实时的查询要好,但必须选择进行实时重建或者定期重建
主表使用 InnoDB ,用 MyISAM 做缓存只读表节约空间 建立额外索引,增加冗余列
计数器表
更新计数器可能会出现并发问题,因此可以使用 rand 进行随机写加快并发更新的速度,读的时候 SUM 一下即可
索引
好处:
- 减少扫描数据量
- 避免排序和临时表
- 将随机IO变为顺序IO 如果使用某个索引进行范围排序,也就无法再使用另一个索引进行排序
快速创建索引
其中一个技巧是先禁用索引,载入数据,再启用 不能禁用的话删除索引也是一样的
B-Tree 索引
值和指针存储在一起 如果索引包含多个列,列的顺序非常重要,MySQL只能高效地使用索引的最左前缀列 现在大部分的引擎使用的都是 B+树索引
B+树索引
InnoDB 使用 B+树索引 与B树的不同点:非叶子节点只存储值,叶子节点存储值和行指针,这样降低了节点的大小,单个页可以存放更多的节点,意味着更少的磁盘IO;叶子节点像链表一样串在一起,方便范围查询;删除操作更简单;快速下沉找值
限制:
- 不是从最左列开始,则无法使用索引
- 不能跳过索引中的列
- 有某个列的范围查询,则其右边的所有列都无法使用索引优化查找
聚簇索引
是一种数据的存储方式,InnoDB使用。数据行的所有字段实际存储在叶子页中,数据行和相邻键值放在一起,是索引列为主键的 B+树,这使得数据的访问更快 数据分布:索引即为整个表
MyISAM 数据分布
使用B+树索引,使用主键列值做索引,叶子节点存储行指针(即物理地址),然后将索引进行前缀压缩,让更多的索引能够放入内存中
哈希索引
只有 memory 引擎支持,会对所有索引列计算哈希值,哈希值为行指针 缺点:无法用于排序,查询必须使用所有的索引列才能使用索引,只支持等值比较 长字符串索引可以转而使用CRC32做索引列,使用触发器进行更新维护,查询效率极高
自适应哈希索引: InnoDB中有的一种索引,当引擎注意到某些索引值被使用得非常频繁的时候,它会在内存中基于 B-tree 索引之上再创建一个哈希索引,使用哈希值而不是键值在B-tree中查找