ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

MySQL

2022-06-07 23:04:24  阅读:117  来源: 互联网

标签:存储 查询 索引 MySQL 磁盘 节点


MySQL架构介绍

  1. 客户端:支持接口(标准的API、JDBC、ODBC、.NET、PHP、Phython等)
  2. 服务端:
    • MySQL软件
      • Server层
        • 连接池:验证与授权、线程、内存与缓存管理
        • 管理服务与工具:备份与恢复、安全、复制、集群、分区管理、事务管理、数据库模板管理、工作台、合并工具
        • 核心业务处理层:
          • SQL接口:数据管理语言和数据定义语言、存储过程、视图、触发器等
          • 解析器:查询\事务 对象优先级
          • 优化控制器:访问路径统计
          • 缓存和缓冲池:全局和局部引擎的缓存和缓冲池
      • 存储层
        • 插件式存储引擎:MyISM、InnoDB、Cluster。。。。。
    • 磁盘文件
      • 文件系统:NTFS、UTS、EXT2/3、NFS、NAS。。。
      • 文件和日志:REDO、UNDO、DATA。。。。

连接池

  • show fulll processlist 查询所有连接
  • show processlist 只能查询前100个连接
  • 通过max_connections控制修改最大连接数

SQL接口:CRUD分流执行SQL语句(执行器)

Parser:解析器

Optimizer:查询优化器

Cache和Buffer:查询缓存(MySQL8.0去掉:缓存命中太差,同一条SQL语句才能命中)

SQL执行过程

 

 

  1.  连接器:客户端通过连接器与服务端简历连接(mysql -uroot -p123456),验证用户,建立连接
  2. 查询缓存
    • SQL语句一致才会存储缓存
    • 表修改缓存则清空
  3. 解析器和预处理
    • 词法分析:按照空格和逗号切割语句
    • 语法分析:鉴别关键字、表名称、列名称、查询条件
    • 形成语法树:
    • 预处理 :检查语法树是否合法(检查权限,列名是否存在、表名是否存在、别名改为表名)

  4. 优化器
    • 解析语法树的执行一般有多种计划
    • 最终只能选择其中一种执行计划去执行
      • 基于成本计算
        • 根据索引的执行情况选择
        • 一般一个SQL语句执行,只会选择一个索引去使用
        • 如果通过join连接的多表,可以再查询计划中选择基表
        • 自己写的SQL语句,不一定按照你写的条件执行
  5. 执行器
    • 按照执行计划调用存储引擎接口,通过存储引擎去操作磁盘中的数据。

 

 

 MySQL的存储引擎

存储引擎针对表制定,存储引擎也是一种性能优化

  1. InnoDB
    • MySQL5.以后默认
    • 特点:行锁、事务
    • 适合于读写不分离,并发高的场景
  2. MyISAM
    • 特点:不支持行锁、不支持事务
    • 适合于读多、写少
    • 写操作时,进行表级锁定
  3. CSV :csv文件
  4. Memory:内存的存储引擎,类似Redis

MySQL磁盘文件

查看磁盘文件位置:show variables like ‘datadir%’;可以通过datadir指定磁盘文件位置。

  1. 数据文件
    • InnoDB
      • frm表结构文件
      • idb数据和索引文件(用户表空间)
    • MyISAM
      • frm表结构文件
      • myd数据文件
      • myi索引文件
    • ibdata系统表空间文件
      • 不断变大
      • 性能优化的一个点
  2. 日志文件
    • binlog:二进制日志文件(数据恢复、主从复制)
    • errlog:错误日志文件 mycentos.err
    • slow_query_log:慢查询日志文件(默认关闭,性能分析)
    • general_query_log:通用查询日志文件;
    • redo_log:重做日志文件(保证事务ACID特性)ib_logfile0、ib_logfile1
    • undo_log:回滚日志文件(保证事务ACID特性)ibdata1
    • relay_log:中继日志文件
  3. 磁盘如何存储数据
    • 随机写(数据文件:性能低)
      • 旋转时间
      • 寻找磁道
      • 寻找扇区
      • 判断扇区是否占用
      • 占用继续上面
    • 顺序写(日志文件:性能高)
      • 旋转时间
      • 寻找磁道
      • 寻找扇区
    •  

MySQL数据在磁盘中存取

  1. 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
          • 一个表中会存在多个索引,非主键索引是不存储数据的(因为数据只存一份,再主键索引树),只存主键值
          • 通过次要索引查找数据,需要先通过次要索引树查找主键,再通过主键所索引树查找数据。
  2. MySQL在磁盘中读取数据

 

索引的磁层原理与使用原则

  1. 索引常用的数据结构
  2. 索引的使用
    • 索引分类
      • 主键索引
        • 索引中的值是唯一的,不允许为空
      • 唯一索引
        • 索引中的值是唯一的,允许为空
      • 普通索引
        • MySQL基本引用类型,没什么限制
      • 全文索引
        • 只能用在char、varchar、text文本类型的字段上。字段长度较大时,如果用普通索引效率低,可以用全文索引
      • 前缀索引
        • 在char、varchar、text文本类型的字段,可以指定索引列长度(前十个字符组成索引),但是数据类型不指定
      • 组合索引
        • 最左前缀原则
        • 建议使用组合索引代替单列索引,主键索引除外
  3. 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未开启

            1. 存储引擎根据索引a=13,b>=15会匹配三条索引记录  三条索引记录会涉及三次回标
            2. 存储引擎将三条记录返回给Server层
            3. Server层进行c=5过滤  两条记录
            4. Server层根据d=‘pdf’过滤 一条记录
          • ICP开启 

            1. 存储引擎根据索引a=13,b>=15会匹配三条记录
            2. 存储引擎根据索引下推的条件c=5在辅助索引树中进行过滤 两条记录涉及两次回表
            3. 存储引擎层会将两条记录返回Server层
            4. Server层进行d='pdf'过滤 一条记录
  4. 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层排序
  5. 索引失效
    • 全值匹配
    • 最佳左前缀原则(多列索引遵循此原则)
      • 带头索引死(不使用索引,全表扫)
      • 中间索引断(带头索引生效,其他索引失效)
    • 不要在索引上计算会失效
    • 索引条件右边的列失效 (不要在索引中间使用 范围比骄)
    • 范围条件右边的列索引失效
    • 尽量使用覆盖索引 selelct 索引1,索引2 from
    • 索引字段上不要使用 != 会索引失效
    • 索引字段使用like不以通配符开头
      • 使用通配符可以用覆盖索引,解决索引失效
    • 索引字段字符串要加单引号
    • 索引字段不要使用or
    • 总结:全值匹配我最爱,最左前缀要遵守。带头大哥不能死,中间兄弟不能断;索引列上少计算,范围之后全失效;Like百分写最右,覆盖索引不写星,不等空值还有or,索引失效要少用。
  6. 索引创建原则
    • 索引需要创建的情况
      • 频繁出现在where、order排序、group by
      • select频繁出现的列,创建组合索引,覆盖索引
      • 多表join关联,on字段两边的字段要创建索引
    • 索引创建的建议
      • 表记录少的不需要
      • 一个表索引记录不要过多
        • 空间占用
        • 时间占用 更新变慢、增加优化器选择时间
      • 频繁更新字段不建议创建索引
      • 区分度低字段(男、女区分数据度不大)
      • InnoDB主键索引建议自增,避免使用长字段
      • 不建议使用无序值作为索引
      • 尽量创建组合索引
      • 字符太长,使用前缀索引
  7. 索引优缺点
    • 优点
      • 提高检索效率,降低磁盘IO
      • 通过索引进行数据排序,降低排序 成本
    • 缺点
      • 占据额外的磁盘空间
      • 对写、更新操作不友好

MySQL锁和事物

  1. 锁划分
    • 按照锁粒度:、
      • 全局锁
      • 表级锁:开销小,加锁快;不会出现死锁;锁粒度大,出现冲突的概率高,并发度最小。
      • 行级锁:开销大,加锁慢;会出现死锁;锁粒度小,出现冲突概率低,并发度也高
    • 按照锁的功能:排他写锁、共享读锁
    • 按照锁的实现方式:悲观锁(物理锁,真正锁)、乐观锁(版本等逻辑控制)

 

标签:存储,查询,索引,MySQL,磁盘,节点
来源: https://www.cnblogs.com/zxy1314/p/16347678.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有