您的位置:首页 > 数据库

一条SQL查询语句是如何执行的

2020-03-27 19:47 363 查看

一条SQL查询语句是如何执行的?

读书笔记-mysql基础架构

平时使用数据库,通常看到的都是一个整体:
如下面最简单的一个查询语句:查询编号为1的用户信息

mysql> select * from user where id ='1';

从mysql的架构出发,看这条查询背后都有哪些过程:

Mysql 可分为Server层和存储引擎两个部分

  • Server 层包括 连接器、查询缓存、分析器、优化器、执行器等。
  • 存储引擎负责数据的存储和提取。其架构模式是插件式,支持 InnoDB、MyISAM、Memory 等多个存储引擎。现在最常用的存储引擎是 InnoDB,它从 MySQL 5.5.5 版本开始成为了默认存储引擎。也可以在创建表时,指定引擎
mysql> create table user(
-> id int(10) unsigned not null auto_increment,
-> name varchar(10) character set utf8,
-> age int(10),
-> primary key(id)
-> )
-> engine=memory
-> ;

连接器

  • 一个用户成功建立连接后,即使你用管理员账号对这个用户的权限做了修改,也不会影响已经存在连接的权限。修改完成后,只有再新建的连接才会使用新的权限设置
  • 连接后,无后续动作,连接会处于空闲状态。Command列为Sleep表示空闲态
mysql> show processlist;
+----+------+-----------+----------+---------+------+----------+------------------+
| Id | User | Host      | db       | Command | Time | State    | Info             |
+----+------+-----------+----------+---------+------+----------+------------------+
|  2 | root | localhost | examples | Query   |    0 | starting | show processlist |
+----+------+-----------+----------+---------+------+----------+------------------+
1 row in set (0.00 sec)
  • 客户端太长时间不操作,连接器自动断开。由参数wait_timeout控制
    建立连接的过程通常是比较复杂的,建议在使用中要尽量减少建立连接的动作,也就是尽量使用长连接。
  • 全部使用长连接会使内存涨得非常快,长期积累会OOM,mysql会异常重启。
    1 定期断开长连接,操作大的内存查询时,断开重连
    2 更新版本,可以在每次执行一个比较大的操作后,通过执行 mysql_reset_connection 来重新初始化连接资源。这个过程不需要重连和重新做权限验证,但是会将连接恢复到刚刚创建完时的状态。

查询缓存

  • MySQL 拿到一个查询请求后,会先到查询缓存看看,之前是不是执行过这条语句。之前执行过的语句及其结果可能会以 key-value 对的形式,被直接缓存在内存中

  • 一般不建议使用缓存,因为查询缓存的失效频繁,因为对一个表的更新会促使缓存清空。除非是一张静态表,不会时常更新。

  • 参数 query_cache_type 设置成 DEMAND,这样对于默认的 SQL 语句都不使用查询缓存

    要使用查询缓存的语句,可以用 SQL_CACHE 显示控制

mysql> select SQL_CACHE * FROM user where id = '1';

分析器

  • 分析器先会做“词法分析”。你输入的是由多个字符串和空格组成的一条 SQL 语句,MySQL 需要识别出里面的字符串分别是什么,代表什么。
  • 做完了这些识别以后,就要做“语法分析”。根据词法分析的结果,语法分析器会根据语法规则,判断你输入的这个 SQL 语句是否满足 MySQL 语法。

优化器

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

执行器

  • 开始执行的时候,要先判断一下你对这个表user 有没有执行查询的权限,如果没有,就会返回没有权限的错误,如下所示 (在工程实现上,如果命中查询缓存,会在查询缓存返回结果的时候,做权限验证。查询也会在优化器之前调用 precheck 验证权限
  • 如果有权限,则打开表执行。根据表的引擎定义,去使用引擎提供的接口。
  • 本例中,调用InnoDB引擎接口取这个表的第一行,判断 ID 值是不是1,如果不是则跳过,如果是则将这行存在结果集中;调用引擎接口取“下一行”,重复相同的判断逻辑,直到取到这个表的最后一行。执行器将上述遍历过程中所有满足条件的行组成的记录集作为结果集返回给客户端

本文是通过学习极客时间“MySQL实战45讲”,做的学习笔记,有错误的地方,请网友提出,大家共同学习,后续陆续更新!扫描下方二维码,可以共同学习。

  • 点赞
  • 收藏
  • 分享
  • 文章举报
rong742954 发布了11 篇原创文章 · 获赞 1 · 访问量 149 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: