基础
第一范式是列不能再细分,第二范式是必须有主键即一个表描述一件事,第三范式是不能有冗余字段
架构
连接器的并发查询数不包括pending线程
缓存已删除
分析器做语法分析
优化器做索引选择,主要依据是索引基数,即索引区分度,计算基数使用采样索引统计
执行器判断对表的权限
存储引擎提供读写接口
redolog WAL实现crash-safa,是循环写,三种写入策略分别写入0buffer,2page以及1磁盘
undolog用于回滚
binlog格式包括,statement,row以及mix,row使用校验和验证数据完整性,mix时会判断statement会不会造成主备数据不一致,和redolog保持双1配置,即事务提交前redolog和binlog都同步到磁盘
relaylog用于重放 redolog的两阶段提交指在事务提交前,需要先依次提交redolog的prepare以及binlog以及redolog的commit,保证redolog和binlog的数据一致性,binglog通过checksum校验完整性,完整则提交redolog不完整则不提交redolog
组提交表示一起提交多个事务的redolog,leader事务提交时会带上组内最大的LSN
更新逻辑即刷脏页,redolog满时会刷脏页
视图
隐藏数据复杂性
权限
用户权限,DB权限,表权限
分区表
有一个frm文件和多个ibd文件
建表
多对多的关系用中间表表达,一对多的关系用明细表表达
存储引擎
innodb支持行级锁
Myisam索引和数据不在同一个文件,而innodb的主键索引和数据都在同一个文件
memory内存表应用于临时表场景
事务
InnoDB实现
ACID:A undoLog实现;c AID实现;I 隔离级别实现;D redolog的WAL实现
显示事务启动时在第一条语句才启动
传播行为 support required
隔离级别 可重复读是mysql,快照读MVCC,当前读更新时使用,幻读由next-key解决
锁
全局锁:FTWRL和read_only
表锁:MDL
Myisam:不会死锁
InnoDB:间隙锁,可重复读,读提交+binglog=row,next-key解决幻读
悲观锁:以上都是
MVCC:readview,回滚+版本可见性:视图数组低水位
死锁:循环等待,冲突行后置
可重复读加锁:单位是next-key,等值查询在唯一索引和普通索引的优化
索引
约束:两个约束会自动创建索引
自增主键:不是连续的,因为一次申请多次且不会回退
自增ID用完时,表ID保持不变,还有rowID,XID,视图数组的trx_id以及thread_id4种ID
索引缺点是索引维护
索引维护会导致页分裂,自增主键少一点,业务逐渐多一点,索引重建使数据紧凑
change_buffer降低读IO,redoLogBuffer降低写IO,由于change_buffer的原因,尽量选择普通索引
联合索引:最左匹配,优化有跳跃索引和ICP
InnoDB的索引模型有BTree和AHI哈希索引,哈希索引只适用于等值比较
优化
通过查询health表或者查询内部统计表判断数据库是否异常
使用where代替having以及使用覆盖索引避免索引失效
查询慢的原因之一是别的线程执行大量更新导致快照回滚,还有一种有损方案就是查询重写
深分页可以使用子查询或者limit优化为利用索引
因为null不适用于不等于条件,所以字段尽量为not null
分表字段的选择依据为避免数据倾斜,分表算法有根据数值划分,哈希取模或者一致性哈希,全局ID的方案有UUID,单表加步长以及雪花。分表方案带来的问题就是读扩散问题
读写分离方案的问题在于过期读,解决方案可以是判断主库无延迟才开放从库读,无延迟指标有位点,GTID以及SBM指标
主备是实现读写分离的方案,原理就是备库的io和sql两个线程
主备延迟可以使用并行复制,即将sql线程改为IO多路复用模型,后面挂一些worker线程,并行度可以是按表分发,按行分发
主备切换有可靠性优先和可用性优先,可靠性优先可以判断SBM指标
主从切换可以基于GTID,主库将与从库GTID之间的差集发给从库
临时表
临时表可以与普通表重名,因为临时表结构在物理和内存中存储都会带上线程ID
临时表的使用场景如union和group by,union因为需要保证唯一性,而group by因为分组条件需要单独存储,group by在没有聚合函数时等同于distinct
sql
DQL的行转列有wmconcat,listagg以及pivot
全表扫描对server层会占满netBuffer,对存储引擎会导致buffer pool全是冷数据,inndoDB对bufferpool做了young和old区域划分的优化
join内部有NLJ,BNL以及BKA三种算法,NLJ和BNL一个使用了被驱动表的索引一个没有使用,BKA是对NLJ的优化,利用了MRR,即在驱动表回表前将ID在内存中排序以实现顺序读盘
删除的性能,drop大于truncate大于delete,delete不会释放空间, 需要进行表重建
expain可以查看执行计划,extra列展示了执行过程中的操作
kill 命令不管是关闭查询还是连接,都不是立即关闭,只是发送信号给阻塞中的线程
对于count函数,myISAM是单独存储,而innodb需要查询,查询耗时count(col)大于count(id)大于count(1)等于count(*0),当然也可以使用计数表和redis等方案计数
order by内部利用了sortBuffer排序,使用的堆排序,全字段排序不用回表rowid需要回表,优先使用全字段排序,行数据量大于阈值则会变为rowid排序