MySQL
2022/6/8 2:20:14
本文主要是介绍MySQL,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
MySQL架构介绍
- 客户端:支持接口(标准的API、JDBC、ODBC、.NET、PHP、Phython等)
- 服务端:
- MySQL软件
- Server层
- 连接池:验证与授权、线程、内存与缓存管理
- 管理服务与工具:备份与恢复、安全、复制、集群、分区管理、事务管理、数据库模板管理、工作台、合并工具
- 核心业务处理层:
- SQL接口:数据管理语言和数据定义语言、存储过程、视图、触发器等
- 解析器:查询\事务 对象优先级
- 优化控制器:访问路径统计
- 缓存和缓冲池:全局和局部引擎的缓存和缓冲池
- 存储层
- 插件式存储引擎:MyISM、InnoDB、Cluster。。。。。
- Server层
- 磁盘文件
- 文件系统:NTFS、UTS、EXT2/3、NFS、NAS。。。
- 文件和日志:REDO、UNDO、DATA。。。。
- MySQL软件
连接池
- show fulll processlist 查询所有连接
- show processlist 只能查询前100个连接
- 通过max_connections控制修改最大连接数
SQL接口:CRUD分流执行SQL语句(执行器)
Parser:解析器
Optimizer:查询优化器
Cache和Buffer:查询缓存(MySQL8.0去掉:缓存命中太差,同一条SQL语句才能命中)
SQL执行过程
- 连接器:客户端通过连接器与服务端简历连接(mysql -uroot -p123456),验证用户,建立连接
- 查询缓存
- SQL语句一致才会存储缓存
- 表修改缓存则清空
- 解析器和预处理
- 词法分析:按照空格和逗号切割语句
- 语法分析:鉴别关键字、表名称、列名称、查询条件
- 形成语法树:
-
预处理 :检查语法树是否合法(检查权限,列名是否存在、表名是否存在、别名改为表名)
- 优化器
- 解析语法树的执行一般有多种计划
- 最终只能选择其中一种执行计划去执行
- 基于成本计算
- 根据索引的执行情况选择
- 一般一个SQL语句执行,只会选择一个索引去使用
- 如果通过join连接的多表,可以再查询计划中选择基表
- 自己写的SQL语句,不一定按照你写的条件执行
- 基于成本计算
- 执行器
- 按照执行计划调用存储引擎接口,通过存储引擎去操作磁盘中的数据。
MySQL的存储引擎
存储引擎针对表制定,存储引擎也是一种性能优化
- InnoDB
- MySQL5.以后默认
- 特点:行锁、事务
- 适合于读写不分离,并发高的场景
- MyISAM
- 特点:不支持行锁、不支持事务
- 适合于读多、写少
- 写操作时,进行表级锁定
- CSV :csv文件
- Memory:内存的存储引擎,类似Redis
MySQL磁盘文件
查看磁盘文件位置:show variables like ‘datadir%’;可以通过datadir指定磁盘文件位置。
- 数据文件
- InnoDB
- frm表结构文件
- idb数据和索引文件(用户表空间)
- MyISAM
- frm表结构文件
- myd数据文件
- myi索引文件
- ibdata系统表空间文件
- 不断变大
- 性能优化的一个点
- InnoDB
- 日志文件
- binlog:二进制日志文件(数据恢复、主从复制)
- errlog:错误日志文件 mycentos.err
- slow_query_log:慢查询日志文件(默认关闭,性能分析)
- general_query_log:通用查询日志文件;
- redo_log:重做日志文件(保证事务ACID特性)ib_logfile0、ib_logfile1
- undo_log:回滚日志文件(保证事务ACID特性)ibdata1
- relay_log:中继日志文件
- 磁盘如何存储数据
-
- 随机写(数据文件:性能低)
- 旋转时间
- 寻找磁道
- 寻找扇区
- 判断扇区是否占用
- 占用继续上面
- 顺序写(日志文件:性能高)
- 旋转时间
- 寻找磁道
- 寻找扇区
-
- 随机写(数据文件:性能低)
MySQL数据在磁盘中存取
- MySQL在磁盘中存数据
- 磁盘和MySQL交互
- 磁盘和操作系统(内核空间)交互
- 磁盘中最小的存储单位是扇面(扇区),默认最小512字节,小于512字节也占用512字节
- 磁盘和操作系统(内核空间)交互最小单位是4K,该大小由操作系统限制
- 操作系统和MySQL应用(用户空间)交互
- 操作系统和MySQL应用交互的最小单位是16K,该大小可以通过参数(innodb_page_size)控制,索引结构中的节点是一个物理页的大小
- 磁盘和操作系统(内核空间)交互
- 思考:100条数据存储在磁盘上如何存储
- 100条数据对应100个磁盘地址,需要通过IO读取100次才能遍历所有数据
- 如何快速查找
- 索引数据结构
- 数据结构学习网站
- Hash
- Memory数据引擎应用的此数据结构,查询快,O(1);不支持范围查询。
- ;对key进行hash计算(数组下标 = hashcode / 数组长度)
- hash表特点
- 一次性把表数据加载到内存中
- hash冲突:
- 多个KV对都存储到同一数组下标下
- 链地址存储解决hash冲突
- 链表越长,查询越慢
- reHash:当数据长度扩充的时候,同一个key再前后两个数组存储位置不一样
- 二叉树
- 二叉树是一种高瘦树
- 按需加载
- 一次加载一次IO
- 一次加载两个节点,防止内存装不下
- 左子树和右子树从小到大
- 特点:会退化成链表
- 平衡二叉树
- 红黑树是一种近似平衡二叉树()
- 左子树和右子树高度差不能超过1,超过1发生左旋、右旋
- 使用平衡二叉树查找的性能接近于二分查找,时间复杂度是O(log2n)
- 存在问题
- 时间复杂度和树高度有关。树高等于查询次数即IO次数,磁道每次查询时间10ms
- 平衡二叉树不支持范围查找,查询从根节点查找,效率不高
- B树(改造二叉树)
- 一个节点可以插入多少个索引?
- 假如一个值(key)weibigint=8字节,每个字节两个指针,每个指针为4个字节,一个字节占用的空间为16个字节,(8 + 4 * 2 = 16)
- 磁盘一次IO读取一页(一个节点)16K的数据量,一个节点可以存储1000个索引(16K / 16 = 1000)
- 树高度为2时,存储的数据为 1000 * 1000 = 1百万(记录)
- 叶子节点之间没有指向
- 叶子节点和非叶子节点之间的值是非重复的
- 每个节点都包含多个元素,非叶子节点中会在元素前中后指向与另一个子节点
-
- 等值查询
- 范围查询
- MySQL特点:所有节点都存储数据
- 一个节点可以插入多少个索引?
- B+树(改造B树)
- 叶子节点之间是有指向的
- 叶子节点和非叶子节点之间值是有重复的
- 左子节点中的最大值小于父节点值
- 右子节点中最小值大于等于父节点值
- MySQL的索引采用B+树对叶子节点进行改造,MySQL使用的B+树的叶子节点之间使用的是双向链表
-
- 等值查询
- 第一次磁盘IO:将磁盘块1加入到内存中,在内存中遍历比较,15 < 28走左路到磁盘寻址磁盘块2
- 第二次磁盘IO:将磁盘块2加载到内存中,在内存中遍历比较,10 < 15 < 17,到磁盘中寻址磁盘块5
- 第三次磁盘IO:将磁盘块5加载到内存中,在内存中遍历比较, 15 = 15,取出data,data存储的是数据则查询结束,磁盘中存储的磁盘地址,则根据磁盘地址查询数据取出。
范围查询(15-26)
- 首先查找值等于15的数据,将缓存结果存储到数据集(查询步骤同上)。
- 查询到15之后,底层的叶子节点是一个有序列表,从磁盘块5向后遍历筛选所有符合条件的数据。
- 等值查询
-
MySQL特点:只有叶子节点存储数据
- 索引数据结构
- MySQL索引结构
- MyISAM索引结构
- 主键索引为非聚簇索引::叶子节点存储索引和数据地址
- 辅助索引为非聚簇索引:叶子节点存储索引和数据地址
InnoDB索引结构
- 主键索引为非聚簇索引::叶子节点存储索引和数据地址
- 主键索引为聚簇索引:叶子节点存储索引和数据
- 一个表只会再主键索引树存储数据
- 辅助索引为非聚簇索引:叶子节点存储索引和数据主键Id
- 一个表中会存在多个索引,非主键索引是不存储数据的(因为数据只存一份,再主键索引树),只存主键值
- 通过次要索引查找数据,需要先通过次要索引树查找主键,再通过主键所索引树查找数据。
- MyISAM索引结构
- 磁盘和MySQL交互
- MySQL在磁盘中读取数据
索引的磁层原理与使用原则
- 索引常用的数据结构
- 数据结构学习网址
- B+树
- Hash
- 索引的使用
- 索引分类
- 主键索引
- 索引中的值是唯一的,不允许为空
- 唯一索引
- 索引中的值是唯一的,允许为空
- 普通索引
- MySQL基本引用类型,没什么限制
- 全文索引
- 只能用在char、varchar、text文本类型的字段上。字段长度较大时,如果用普通索引效率低,可以用全文索引
- 前缀索引
- 在char、varchar、text文本类型的字段,可以指定索引列长度(前十个字符组成索引),但是数据类型不指定
- 组合索引
- 最左前缀原则
- 建议使用组合索引代替单列索引,主键索引除外
- 主键索引
- 索引分类
- MySQL索引实现
- MyISAM索引(B+树)
- 主键索引
- 等值查询
- 范围查询
- 辅助索引(B+树)
- 主键索引
- InnoDB索引(一个索引一个索引树)
- 主键索引(聚簇索引) 辅助索引(非聚簇索引)
- 叶子节点存储的时主键索引的key值
- 回表,回到主键索引树查询数据
- 组合索引(辅助索引)
- 针对多列创建索引,索引中的列是有顺序的
- 组合索引存储
-
组合索引查找
- 最左匹配原则
- 组合索引(a,b,c)相当于创建三个索引(a;a,b;a,b,c),在where条件里,必须有a,才能使用索引,a可以在条件最右侧,优化器会自动优化到最左侧
- 书写SQL的顺序不一定是执行顺序,优化器会优化
- 使用组合索引时,MySQL会一直向右查询,直到遇到(<,>,between,like)范围查询
- 何时创建组合索引
- 频繁出现在where条件中的的非主键列,建议创建组合索引
- 频繁出现在order by和group by中的列,建议按照顺序去创建索引(顺序不一致用不到索引,优化器不能优化,因为order by是明确需求)
- 常出现在select语句中列也建议创建组合索引(所以不建议使用*)
- 覆盖索引
- 防止了回表(一次回标,多次IO),辅助索引中查找到的一条记录,会进行一次回表
- 主要是针对select中的列进行优化,如果查找的select列,就不想去主键索引中查找对应的列,查询数据了
-
-
红色标识的字段,均用到索引覆盖
-
紫色框标识的由于有字段d,不在组合索引列,需要回表,没有用到覆盖索引
-
- 索引下推ICP
- 索引下推是为了减少回表次数
- 索引下推设置参数:Index_Condition_PushDown
- 展示MySQL优化器中优化参数开关 show variables like ‘optimizer_switch’
- 关闭索引下推(ICP)set optimizer_switch='index_Condition_PushDown=off';
-
-
ICP未开启
- 存储引擎根据索引a=13,b>=15会匹配三条索引记录 三条索引记录会涉及三次回标
- 存储引擎将三条记录返回给Server层
- Server层进行c=5过滤 两条记录
- Server层根据d=‘pdf’过滤 一条记录
-
ICP开启
- 存储引擎根据索引a=13,b>=15会匹配三条记录
- 存储引擎根据索引下推的条件c=5在辅助索引树中进行过滤 两条记录涉及两次回表
- 存储引擎层会将两条记录返回Server层
- Server层进行d='pdf'过滤 一条记录
-
- MyISAM索引(B+树)
- explain工具查看执行计划
- 执行explain查询计划:explain select * from table_name;
- id:标识符(多张表时标识哪个先执行)
- select_type:查询类型(子查询,关联查询)
- 展示单位查询的查询类型
- simple 简单查询不需要unton和子查询(列为查询语句)
- primary 主查询(区分主表、关联表或者子表)
- subquery 子查询
- derived from字句中出现子查询,就是派生表
- table:查询表名称
- partitions:匹配的分区,表被分区时才会用到
- type:join类型
- 单位查询的连接类型或访问类型
- System 效率最高 说明表要么只有一条记录,要么是空表
- const :使用到唯一或者主键索引,单表,where条件是一个常量值
- eq_ref:等值连接(join...on中的on)的列用到唯一或者主键列,多表
- ref:等值连接(join...on中的on)的列用到非唯一索引列,多表;或者使用最左前缀
- fulltext
- req_or_null
- unique_subquery
- index_subquery
- rang:组合索引,第二个索引列用的范围(> < ...)
- index_merge
- index :全部索引扫描(select a from table;a是索引)一般是用到覆盖索引
- ALL 效率最低(全表扫描,没用索引)select a,d from table;a是索引,d不是索引
-
除all之外都用到索引;除index_merge,其他只可以用一个索引;优化时最少要用到rang级别
- 单位查询的连接类型或访问类型
- possible_keys:此次查询中可能选用的索引
- key:此次查询中确切使用到的索引
- ref:哪个字段或常数与key一起使用
- rows:显示查询一共扫描了多少行
- filtered:表示此次查询条件所过滤的数据的百分比
- extra:额外的信息
- using idex 使用到覆盖索引
- 没有using where 索引用来查找数据;
- 如果同时出现using where表明索引用来查找键值
- using where 表示对存储引擎层返回结果在Server层过滤,过滤字段无索引
- using index condition 用到索引下推
- using filesort 说名排序没有用到index 在Server层排序
- using idex 使用到覆盖索引
- 执行explain查询计划:explain select * from table_name;
- 索引失效
- 全值匹配
- 最佳左前缀原则(多列索引遵循此原则)
- 带头索引死(不使用索引,全表扫)
- 中间索引断(带头索引生效,其他索引失效)
- 不要在索引上计算会失效
- 索引条件右边的列失效 (不要在索引中间使用 范围比骄)
- 范围条件右边的列索引失效
- 尽量使用覆盖索引 selelct 索引1,索引2 from
- 索引字段上不要使用 != 会索引失效
- 索引字段使用like不以通配符开头
- 使用通配符可以用覆盖索引,解决索引失效
- 索引字段字符串要加单引号
- 索引字段不要使用or
-
总结:全值匹配我最爱,最左前缀要遵守。带头大哥不能死,中间兄弟不能断;索引列上少计算,范围之后全失效;Like百分写最右,覆盖索引不写星,不等空值还有or,索引失效要少用。
- 索引创建原则
- 索引需要创建的情况
- 频繁出现在where、order排序、group by
- select频繁出现的列,创建组合索引,覆盖索引
- 多表join关联,on字段两边的字段要创建索引
- 索引创建的建议
- 表记录少的不需要
- 一个表索引记录不要过多
- 空间占用
- 时间占用 更新变慢、增加优化器选择时间
- 频繁更新字段不建议创建索引
- 区分度低字段(男、女区分数据度不大)
- InnoDB主键索引建议自增,避免使用长字段
- 不建议使用无序值作为索引
- 尽量创建组合索引
- 字符太长,使用前缀索引
- 索引需要创建的情况
- 索引优缺点
- 优点
- 提高检索效率,降低磁盘IO
- 通过索引进行数据排序,降低排序 成本
- 缺点
- 占据额外的磁盘空间
- 对写、更新操作不友好
- 优点
MySQL锁和事物
- 锁划分
- 按照锁粒度:、
- 全局锁
- 表级锁:开销小,加锁快;不会出现死锁;锁粒度大,出现冲突的概率高,并发度最小。
- 行级锁:开销大,加锁慢;会出现死锁;锁粒度小,出现冲突概率低,并发度也高
- 按照锁的功能:排他写锁、共享读锁
- 按照锁的实现方式:悲观锁(物理锁,真正锁)、乐观锁(版本等逻辑控制)
- 按照锁粒度:、
这篇关于MySQL的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-16MySQL资料:新手入门教程
- 2024-11-16MySQL资料:新手入门教程
- 2024-11-15MySQL教程:初学者必备的MySQL数据库入门指南
- 2024-11-15MySQL教程:初学者必看的MySQL入门指南
- 2024-11-04部署MySQL集群项目实战:新手入门教程
- 2024-11-04如何部署MySQL集群资料:新手入门指南
- 2024-11-02MySQL集群项目实战:新手入门指南
- 2024-11-02初学者指南:部署MySQL集群资料
- 2024-11-01部署MySQL集群教程:新手入门指南
- 2024-11-01如何部署MySQL集群:新手入门教程