mysql基础

  • MySQL的基本架构
MySQL可以分为Server层和存储引擎层
  • Server层包括:连接器、查询缓存、分析器、优化器、执行器等,涵盖MySQL大多数核心业务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、试图等。
  • 存储引擎层负责数据的存储和提取。其架构模式是插件式的,支持InnoDB、MyISAM、Memory等多个存储引擎。最常用的是InnoDB,从MySQL 5.5.5版本开始成为默认存储引擎。
  • 也可以使用其他存储引擎,比如在create table的时候语句中使用 engine=memory,来指定使用内存引擎创建表。不同存储引擎的表数据存取方式不同,支持的功能也不同。
连接器
  • 连接器负责跟客户端建立连接、获取权限、维持和管理连接。
    连接命令:mysql -h$ip -P$port -u$user -p
  • 查看状态命令:
  • 如果太长时间无操作,连接器就会自动断开。时间由wait_timeout控制的,默认值是8小时。Connect_timeout 指的是“连接过程中”的等待时间.
  • 数据库里面也有长连接和短链接,建立连接的过程通常比较复杂,所以尽量少建立连接的动作,尽量使用长连接。
    但是全部使用长连接后,可能会导致MySQL占用内存涨得特别快,这是因为MySQL在执行过程中临时使用的内存是管理在连接对象里面大的。这些资源会在连接断开的时候才释放。所以如果长连接积累下来,可能导致内存占用太多,被系统强行杀掉(OOM),从现象上看就是MySQL异常重启了。
    解决1:定期断开长连接,或者程序判断执行过一个占用内存的大查询后,断开连接,之后再重连。
    解决2:MySQL5.7或者更新的版本,执行一次较大的操作后,通过执行mysql_reset_connection来重新初始化连接资源。这个过程不需要重新做权限验证。
查询缓存
  • 如果查询命中缓存,MySQL不需要执行后面的复杂操作,直接返回结果
    MySQL会将之前执行过的语句及其结果可能会以key-value,直接缓存再内存中。key是查询语句,value是查询结果。
  • 但是大多数情况下建议不要使用查询缓存
    因为查询缓存往往弊大于利.
    查询缓存的失效非常频繁,只要有对一个表的更新,这个表上所有的查询缓存都会被清空。对于更新压力大的数据库来说,查询缓存的命中率会非常低。
    除非你的业务就是一张静态表,很长时间才跟新一次。比如一个系统配置表。
  • 按需使用查询缓存
    可以将参数query_cache_type设置成DEMAND,这样对于默认的SQL都不适用查询缓存。而对于你确定要使用的查询缓存的语句,可以用SQL_CACHE显示指定,比如:mysql> select SQL_CACHE * from T where ID=10;
  • MySQL8.0版本直接将查询缓存的整个功能块删掉了。
分析器
  • 对SQL语句做解析,
  • 先做“词法分析”,分析字符串分别是什么,代表什么。是查询还是添加,字符串“T”识别成“表名T”,字符串“ID”识别成“列ID”。
  • 再做“语法分析”根据语法规则,判断你输入的这个SQL语句是否满足MySQL语法。
优化器
  • 在表里有多个索引的时候,决定使用哪个索引;或者在一个语句有多个关联(join)的时候,决定各个表的连接顺序。
  • 优化器阶段完成后,这个语句的执行方案就确定了,然后进入执行器阶段。
  • 执行器
    • 开始执行的时候,要判断一下你对这个表有没有查询的权限,如果没有,就会返回权限错误。
      mysql> select * from T where ID=10;
      ERROR 1142 (42000): SELECT command denied to user 'b'@'localhost' for table 'T'
      如果命中查询缓存,会在查询返回结果的时候,做权限验证。
    • 以这条语句为例的执行过程:mysql> select * from T where ID=10;
      • 调用InnoDB引擎接口取这个表大的第一行,判断ID值是不是10,如果不是跳过,如果是则将这行存在结果集中;
      • 调用引擎接口取“下一行”,重复相同的判断逻辑,直到取到这个表的最后一行。
      • 执行器将上述遍历过程中所有满足条件的行组成的记录作为结果集返回给客户端。
    • 数据库的慢查询日志中看到一个 rows_examined的字段,表示这个语句执行过程中扫描了多少行。这个值就是在执行器每次调用引擎获取数据行的时候累加的。在有些场景下,执行器调用一次,在引擎内部扫描了多行。因此引擎扫描行数跟 rows_examined 并不是完全相同。
  • 小结
  • 学员回答
    《高性能mysql》里提到解析器和预处理器。
    解析器处理语法和解析查询, 生成一课对应的解析树。
    预处理器进一步检查解析树的合法。比如: 数据表和数据列是否存在, 别名是否有歧义等。如果通过则生成新的解析树,再提交给优化器。
  • 为什么对权限的检查不在优化器之前做?
    作者回复:有些时候,SQL语句要操作的表不只是SQL字面上那些。比如如果有个触发器,得在执行器阶段(过程中)才能确定。优化器阶段前是无能为力的

posted on 2019-08-28 21:12  拾掇的往昔  阅读(484)  评论(0编辑  收藏  举报

导航