zoukankan      html  css  js  c++  java
  • MySql 实战45讲笔记 : 01

    01基础架构: 一条SQL查询语句是如何执行的

    一般来说 MySql 分为Server 层以及存储引擎层两部分

    • Server 层包括连接器、查询缓存、分析器、优化器、执行器等。涵盖了MySql 的大多数核心服务功能。所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等。
    • 存储引擎层负责数据的存储和提取,其架构模式是插件式的,支持InnoDB, MyISAM, Memory 等多个存储引擎,现在最常用的引擎是InnoDB, 如果在create table 建表的时候,不指定引擎类型,默认使用的就是InnoDB,

    连接器
    连接器负责跟客户端建立连接、获得权限、位置和管理连接。连接命令一般是这么写的。

    mysql -h$ip -P$port -u$user -p
    

    输完命令之后,你就需要在交互对话里面输入密码。虽然密码也可以直接跟在-p后面写在命令行中,但这样可能会导致你的密码泄露。如果你连的是生产服务器,强烈建议你不要这么做。
    一个用户成功建立连接后,即使你用管理员账号对这个用户的权限做了修改,也不会影响已经存在连接的权限。修改完成后,只有再新建的连接才会使用新的权限设置。
    客户端如果太长时间没动静,连接器就会自动将它断开。这个时间是由参数wait_timeout控制的,默认值是8小时。
    数据库里面,长连接是指连接成功后,如果客户端持续有请求,则一直使用同一个连接。短连接则是指每次执行完很少的几次查询就断开连接,下次查询再重新建立一个。
    但是全部使用长连接后,你可能会发现,有些时候MySQL占用内存涨得特别快,这是因为MySQL在执行过程中临时使用的内存是管理在连接对象里面的。这些资源会在连接断开的时候才释放。所以如果长连接累积下来,可能导致内存占用太大,被系统强行杀掉(OOM),从现象看就是MySQL异常重启了。

    查询缓存
    连接建立完成后,你就可以执行select语句了。执行逻辑就会来到第二步:查询缓存。

    MySQL拿到一个查询请求后,会先到查询缓存看看,之前是不是执行过这条语句。之前执行过的语句及其结果可能会以key-value对的形式,被直接缓存在内存中。key是查询的语句,value是查询的结果。如果你的查询能够直接在这个缓存中找到key,那么这个value就会被直接返回给客户端。

    但是大多数情况下我会建议你不要使用查询缓存,为什么呢?因为查询缓存往往弊大于利。
    查询缓存的失效非常频繁,只要有对一个表的更新,这个表上所有的查询缓存都会被清空。除非你的业务就是有一张静态表,很长时间才会更新一次。比如,一个系统配置表,那这张表上的查询才适合使用查询缓存。需要注意的是,MySQL 8.0版本直接将查询缓存的整块功能删掉了,也就是说8.0开始彻底没有这个功能了。

    分析器
    分析器先会做“词法分析”,根据词法分析的结果,语法分析器会根据语法规则,判断你输入的这个SQL语句是否满足MySQL语法。

    优化器
    优化器是在表里面有多个索引的时候,决定使用哪个索引;或者在一个语句有多表关联(join)的时候,决定各个表的连接顺序。

    mysql> select * from t1 join t2 using(ID)  where t1.c=10 and t2.d=20;
    

    既可以先从表t1里面取出c=10的记录的ID值,再根据ID值关联到表t2,再判断t2里面d的值是否等于20。
    也可以先从表t2里面取出d=20的记录的ID值,再根据ID值关联到t1,再判断t1里面c的值是否等于10。
    这两种执行方法的逻辑结果是一样的,但是执行的效率会有不同,而优化器的作用就是决定选择使用哪一个方案。

    执行器

    • 开始执行的时候,要先判断一下你对这个表T有没有执行查询的权限,如果没有,就会返回没有权限的错误。
    • 如果有权限,就打开表继续执行。打开表的时候,执行器就会根据表的引擎定义,去使用这个引擎提供的接口。
    mysql> select * from T where ID=10;
    
    ERROR 1142 (42000): SELECT command denied to user 'b'@'localhost' for table 'T'
    

    如果有权限,就打开表继续执行。打开表的时候,执行器就会根据表的引擎定义,去使用这个引擎提供的接口。

    比如我们这个例子中的表T中,ID字段没有索引,那么执行器的执行流程是这样的:

    • 调用InnoDB引擎接口取这个表的第一行,判断ID值是不是10,如果不是则跳过,如果是则将这行存在结果集中;
    • 调用引擎接口取“下一行”,重复相同的判断逻辑,直到取到这个表的最后一行。
    • 执行器将上述遍历过程中所有满足条件的行组成的记录集作为结果集返回给客户端

    对于有索引的表,执行的逻辑也差不多。第一次调用的是“取满足条件的第一行”这个接口,之后循环取“满足条件的下一行”这个接口,这些接口都是引擎中已经定义好的。

  • 相关阅读:
    2020软件工程作业04
    2020软件工程作业03
    一个我一定会完成的web学习项目
    2020软件工程作业02
    2020软件工程作业01
    423团队选题报告
    计算与软件工程作业五
    计算与软件工程第四次作业
    计算与软件工程第三次作业
    计算与软件工程作业二
  • 原文地址:https://www.cnblogs.com/wsl-hitsz/p/14976156.html
Copyright © 2011-2022 走看看