MySQL笔记

 

MySQL体系结构

  • Connector:接入方连接器
  • Management Services & Utilities:系统管理和控制工具,dump、分区管理等
  • Connection Pool:连接池
  • Parser:解析器
  • Optimizer:查询优化器
  • Caches & Buffers:缓存区
  • Pluggable Storage Engines:插件式存储引擎

MySQL体系结构

执行顺序

MySQL执行顺序

存储引擎

  • 可插拔式:插件式
  • 表级:可每张表单独配置对应的存储引擎
  • 不管表使用什么储存引擎,都会生成frm文件,存储表的定义

CSV

  • 不支持索引
  • 列必须为not null
  • 不能自增
  • 数据存储格式为CSV文件,可以直接编辑

Archive

  • 数据文件格式为ARZ
  • 会对数据进行压缩(zlib)
  • 只支持insert和select操作
  • MySQL 5.5之前不支持索引,5.5之后支持对自增ID列创建索引
  • 行锁

Memory

  • 数据存储在内存中,服务重启会丢失
  • 支持hash索引、B- Tree索引
  • 所有字段长度固定(32),无法使用text、blob等大字段

MyISAM

  • MySQL 5.5之前默认引擎
  • 不支持事务
  • 不支持外键
  • 3个表文件(frm:表定义;MYD:数据;MYI:索引)
  • 非聚集索引
  • 表锁
  • 内置统计器统计数据变化,select count不加条件时无需进行数据扫描

InnoDB

  • MySQL 5.5之后默认引擎
  • 支持事务
  • 行锁
  • 支持外键
  • 主键索引:聚集索引;其他索引:非聚集索引

对比

功能 MyISAM InnoDB
B-tree 索引 支持 支持
索引种类 非聚集索引 聚集索引 + 非聚集索引
数据压缩 支持 支持
数据缓存 - 支持
索引缓存 支持 支持
外键 - 支持
事务 - 支持
MVCC - 支持

索引

  • 为了加快数据检索效率而存在的数据结构
  • 可以减少扫描的数据量
  • 可以将随机IO变为顺序IO
  • 可以在特定的分组与排序时,避免使用临时表

聚集索引

数据物理存储顺序与键值顺序一致,如InnoDB主键索引

非聚集索引

数据存储顺序与键值顺序不一致,如MyiSAM索引,InnoDB非主键索引

InnoDB索引数据结构

B+树

  • 除了根之外的每个节点都包含最少包含[m/2]个元素,最多包含m个元素
  • 对于任意节点,最多有m个子数
  • 对于所有非叶子节点,元素数与子树数相等
  • 所有的叶子节点都在相同的高度上,按顺序排列

B+Tree

离散性

字段离散性 = select distinct 字段 / select 字段

离散性越大,走索引时效率越高

覆盖索引

select 列能通过索引节点中的关键字直接返回

覆盖索引能将随机IO变为顺序IO,提高查询效率

几大原则

最左匹配原则

索引匹配从最左字段开始,直到遇到<,>,<>,like等为止

离散度高原则

离散度越大,索引筛选效率越高

最少空间原则

创建索引的字段长度越小越好

联合索引优先原则

联合索引筛选效率优于单值索引

执行计划

Explain + select SQL

怎么查看

EXPLAIN select * from table1 where Id in (select table1Id from table2 where table2Id = 1) 

执行计划

Id

Id越大,越先执行

Id相同,从上往下执行

select_type
  • SIMPLE:简单的select,不包含子查询和union
  • PRIMARY:包含子查询或union,最外层查询为primary
  • SUBQUERY:子查询
  • MATERIALIZED:where in 的子查询
  • UNION:union 后的查询
  • UNION RESULT:从union结果中获取数据的select
Type
  • System:查询系统表
  • Const:走索引一次就找到了
  • Eq_ref:通过唯一索引、主键索引扫描
  • Ref:通过其他索引扫描,返回单一值的情况(=)
  • Range:通过索引扫描,返回一个范围的数据(<>)
  • Index:通过索引全表扫描
  • All:全表扫描

执行效率

System > Const > eq_ref > ref> range > index > all

Table

查询表的名称或别名

Possible_keys

可能用到的索引

Key

实际用的索引

Rows

大致需要读取的行数

Filtered

返回行占rows的百分比

extra
  • Using index:使用了覆盖索引
  • Using where:使用了where过滤
  • Using temporary:使用了临时表
  • Using filesort:使用了外部文件进行排序,没有使用表内的索引
  • select tables optimized away:使用了MyISAM等select count优化或基于索引的min、max优化,直接返回数据

事务

ACID

  • 原子性Atomicty:数据修改要么一起成功,要么一起失败
  • 一致性Consistency:事务操作的数据变更及状态改变是一致的
  • 隔离性Isolation:一个事务的数据在提交前,对其他事务是不可见的
  • 持久性Durability:事务所做的变更,提交后将会永久保存

隔离级别

  • 读未提交(Read Ucommitted):没提交的事务对其他事务也是可见的,可能遇到脏读(dirty read)
  • 读提交(Read Committed):只能读取自己事务内的修改和其他事务已经提交的修改,可能遇到不可重复读(nonrepeatable read)
  • 可重复读(Repeatable Read):同一事务多次读取同一数据的结果是一样的,可能遇到幻读(phantom read)
  • 序列化(serializable):事务串行执行

共享锁(share lock)

读锁,多个事务可共享此锁,但是只能读数据,不可修改数据

锁行

排它锁(exclusive lock)

写锁,不可与其他锁共存,获取排他锁后可以对数据进行读取和修改

锁行

意向共享锁(intention share lock)

当事务想要给数据行加共享锁时,需要先取得此表的意向共享锁;意向共享锁之间是相互共享的

锁表

意向排它锁(intention exclusive lock)

当事务想要给数据行加排他锁时,先要给表加意向排他锁;意向排他锁之间是互相共享的

锁表

自增锁(auto-inc lock)

针对自增列加的特殊表锁

记录锁(record lock)

锁住具体记录的索引项。走索引进行等值匹配,且能匹配到数据时使用

间隙锁(gap lock)

锁住一段区间(左开右开)。走索引检索是,没有匹配到具体的记录时使用,只在RR隔离级别存在

临键锁(Next key lock)

锁住具体记录即一段区间(左开右闭)。走索引进行范围查找,并能找到记录时使用。

多版本并发控制 MVCC(Multiversion concurrency control)

对事务内处理的数据做多版本管理,避免写操作对读操作的阻塞。

InnoDB MVCC在每张表会添加DB_TRX_ID(数据行事务版本号)、DB_ROLL_PT(数据行删除事务版本号)两个隐藏列

  • 事务开始时,从系统获取事务全局ID
  • 事务内insert数据的DB_TRX_ID字段为此事务ID
  • 事务内delete数据的DB_ROLL_PT字段修改为此事务ID
  • 事务内update的数据,将老数据的DB_ROLL_PT字段修改为此事务ID;Copy一条新数据出来,DB_TRX_ID字段为此事物ID
  • 事务内查询的数据为DB_TRX_ID比当前事务ID小的数据 + DB_ROLL_PT为null或比当前事务ID大的数据

日志

Redo log

记录事务操作的最新数据,用来实现持久化

Uodo log

记录事务操作前的数据,用来实现原子性

Bin log

记录会改变数据的操作日志,常用来做主从同步

Error log

记录mysql服务的错误日志

General log

记录客户端执行的sql语句

Show log

记录慢查询和没走索引的sql

Relay log

中继日志,常与bin log配合来做主从同步