大家好!这是我的第一篇文章。
这篇文章我将介绍一条sql查询语句是如何执行的
下面是mysql架构图:
总的来说,mysql可以分为两部分:服务器层和存储引擎层。
服务器层包括连接器、查询缓存、解析器、优化器、执行器等,包含mysql的大部分核心服务功能,以及所有内置功能(如日期、时间、数学和加密)功能)。所有跨存储引擎的功能,例如存储过程、触发器和视图都在这一层实现。
存储引擎层负责数据的存储和检索。其架构是基于插件的,支持innodb、myisam、memory等多种存储引擎。从mysql 5.5.5开始,innodb成为mysql的默认存储引擎。
创建表时可以使用带有engine=memory的create table语句指定内存引擎。
不同的存储引擎共享同一个server层
连接器
第一步是连接数据库,这需要连接器。连接器负责与客户端建立连接、获取权限并维护和管理连接。连接命令为:
mysql -h$ip -p$port -u$user -p登录后复制
该命令用于与服务器建立连接。完成经典的 tcp 握手后,连接器将使用提供商的用户名和密码来验证您的身份。
- 如果用户名或密码不正确,您将收到“用户错误导致访问被拒绝”的消息,并且客户端程序将终止。
- 如果身份验证成功,连接器将从权限表中检索当前帐户的权限。此连接期间的所有权限检查都依赖于此初始检索。
这意味着一旦连接成功建立,管理员对用户权限所做的任何更改都不会影响现有连接的权限。只有新连接才会使用更新后的权限设置。
连接建立后,如果没有后续动作,则连接进入空闲状态,可以使用show processlist命令查看:
如果客户端长时间处于不活动状态,连接器将自动断开连接。持续时间由 wait_timeout 参数控制,默认为 8 小时。
如果连接终止并且客户端发送请求,则会收到错误消息:在查询期间丢失与 mysql 服务器的连接。要继续,您需要重新连接,然后执行请求。
在数据库中,持久连接是指客户端在成功连接后为连续请求保持相同的连接。短连接是指在几次查询后断开连接并重新连接以进行后续查询。
由于连接过程比较复杂,建议开发过程中尽量减少连接的创建,即尽可能使用持久连接。
但是,当使用持久连接时,mysql 的内存使用量可能会显着增加,因为执行期间使用的临时内存是在连接对象内管理的。仅当连接终止时,这些资源才会被释放。如果长连接不断累积,可能会导致内存使用过多,导致系统强行终止mysql(oom),导致意外重启。
解决方案:
- 定期断开持久连接。使用连接一段时间或执行消耗过多内存的查询后,请断开连接并重新连接以进行后续查询。
- 如果您使用的是 mysql 5.7 或更高版本,您可以在执行资源密集型操作后使用 mysql_reset_connection 来重新初始化连接资源。此过程不需要重新连接或重新验证,而是将连接重置为刚刚创建的状态。
查询缓存
注意:从 mysql 8.0 开始,查询缓存功能已被完全删除,因为其弊大于利。
当mysql收到查询请求时,它首先检查查询缓存,看看这个查询之前是否已经执行过。之前执行过的查询及其结果以键值对的形式缓存在内存中。键是查询语句,值是结果。如果在查询缓存中找到该键,则将该值直接返回给客户端。
如果在查询缓存中未找到查询,则过程继续。
为什么查询缓存弊大于利?
查询缓存失效的情况非常频繁地发生。对表的任何更新都会清除与该表相关的所有查询缓存,导致缓存命中率非常低,除非该表是静态配置表。
mysql提供了一种“按需”的方法来使用查询缓存。通过将参数query_cache_type设置为demand,sql语句默认不会使用查询缓存。要使用查询缓存,可以显式指定 sql_cache:
select sql_cache * from t where id=10;登录后复制
解析器
如果查询缓存没有命中,则语句执行过程开始。 mysql 首先需要了解要做什么,因此它会解析 sql 语句。
解析器首先执行词法分析。输入的 sql 语句由字符串和空格组成,mysql 会对其进行分析,以识别每个部分代表的含义。例如select标识为查询语句,t标识为表名,id标识为列。
词法分析之后,进行语法分析。语法分析器根据词法分析的结果判断sql语句是否符合mysql的语法规则。
如果存在语法错误,将会显示类似“您的 sql 语法有错误”的错误消息。例如,在以下查询中,select 关键字拼写错误:
mysql> elect * from t where id=1; error 1064 (42000): you have an error in your sql syntax; check the manual that corresponds to your mysql server version for the right syntax to use near 'elect * from t where id=1' at line 1登录后复制
优化器
解析之后,mysql 知道你想做什么。接下来,优化器确定如何执行。
当一个表有多个索引时,优化器决定使用哪个索引,或者当查询涉及多个表时,优化器决定表连接的顺序。例如,在以下查询中:
select * from t1 join t2 using(ID) where t1.c=10 and t2.d=20;登录后复制
查询可以从检索 t1 或 t2 中的值开始。两种方法产生相同的逻辑结果,但它们的性能可能不同。优化器的作用是选择最有效的计划。
优化阶段结束后,流程进入执行器。
执行者
执行器开始执行查询。
执行前,首先检查当前连接是否有查询表的权限。如果没有,则返回错误,指示权限不足。 (从查询缓存返回结果时也会执行权限检查。)
如果授予权限,则打开表并继续执行。在此过程中,执行器根据表的引擎定义与存储引擎进行交互。
例如,假设表 t 在 id 列上没有索引。执行者的执行过程如下:
- 调用innodb引擎接口取出表的第一行,检查id值是否为10,如果不是则跳过;如果是,则将其添加到结果集中。
- 调用引擎接口获取“下一行”,重复相同的逻辑,直到检查完所有行。
- 执行器将累积的结果集返回给客户端。
至此,查询完成。
对于索引表,该过程涉及使用引擎的预定义方法来迭代获取“第一个匹配行”和“下一个匹配行”。
慢查询日志中,rows_examined字段表示查询执行过程中扫描的行数。每次执行器调用引擎检索数据行时,该值都会累加。
在某些情况下,对执行器的单次调用可能涉及在引擎内部扫描多行。因此,引擎扫描的行数不一定等于 rows_examined.
结尾
感谢您的阅读!希望文章对您有所帮助。
以上就是SQL查询语句是如何执行的的详细内容,更多请关注慧达安全导航其它相关文章!
免责 声明
1、本网站名称:慧达安全导航
2、本站永久网址:https//www.huida178.com/
3、本站所有资源来源于网友投稿和高价购买,所有资源仅对编程人员及源代码爱好者开放下载做参考和研究及学习,本站不提供任何技术服务!
4、本站所有资源的属示图片和信息不代表本站的立场!本站只是储蓄平台及搬运
5、下载者禁止在服务器和虚拟机下进行搭建运营,本站所有资源不支持联网运行!只允许调试,参考和研究!!!!
6、未经原版权作者许可禁止用于任何商业环境,任何人不得擅作它用,下载者不得用于违反国家法律,否则发生的一切法律后果自行承担!
7、为尊重作者版权,请在下载24小时内删除!请购买原版授权作品,支持你喜欢的作者,谢谢!
8.若资源侵犯了您的合法权益,请持 您的版权证书和相关原作品信息来信通知我们!QQ:1247526623我们会及时删除,给您带来的不便,我们深表歉意!
9、如下载链接失效、广告或者压缩包问题请联系站长处理
10、如果你也有好源码或者教程,可以发布到网站,分享有金币奖励和额外收入!
11、本站资源售价只是赞助,收取费用仅维持本站的日常运营所需
12、因源码具有可复制性,一经赞助,不得以任何形式退款。
13、本文内容由网友自发贡献和站长收集,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系1247526623@qq.com
转载请注明出处: 慧达安全导航 » SQL查询语句是如何执行的
发表评论 取消回复