MySQL研究:SQL语句执行过程详解
当你想让MySQL以更高的性能运行查询时,最好的方法就是了解如何优化和执行MySQL查询。一旦理解了这一点,优化查询的任务就是遵循某些规则,以便它以预期和可接受的方式运行。如下图所示,当向MySQL发送请求时,MySQL到底做了什么:
- 客户端向服务器发送查询。
- 服务器首先检查请求缓存。如果命中缓存,则立即返回缓存的结果。如果没有,请转到下一步。
- 服务器进行SQL解析和处理,然后优化器创建合适的执行计划。
- MySQL根据优化器生成的执行计划调用存储引擎的API来执行查询。
- 将结果返回给客户。
查询缓存
MySQL查询缓存存储查询返回的完整结构。当查询命中缓存时,MySQL立即返回结果,绕过解析、优化和执行的过程。如果这些表发生变化,所有与该表相关的存储数据都将失效。 MySQL将缓存存储在引用表中,由哈希值指定。这个哈希值包括以下因素,即请求、当前查询的数据、客户端协议版本以及其他可能影响返回响应的信息。 。 MySQL在判断缓存是否命中时,不会监听查询语句,而是直接使用客户端原来发送的SQL语句等信息。因此,字符的差异,例如空格、注释等,都会导致缓存未命中。例如,包含 NOW() 或 CURRENT_DATE() 函数的查询将不会被保存。 MySQL数据库中包含用户定义函数、存储函数、用户变量、临时表、系统表或任何列权限的表将不会被存储。因为查询包含不安全函数,因为MySQL在检查查询缓存之前不会检查查询语句,所以它不知道语句中是否存在不安全函数。事实是,如果查询语句包含不安全操作,则查询结果不会被缓存,因为在查询缓存中找不到查询结果。
- query_cache_type:是否启用查询缓存。可设置为“关”、“开”和“需求”。DEMAND 表示只有请求语句中显式的 SQL_CACHE 语句才会被放入请求缓存中。
- query_cache_size:查询缓存使用的总内存空间。
- query_cache_min_res_unit:在查询缓存中分配内存块时的最小单位。较小的值可以减少由于碎片而浪费的内存量,但会导致更频繁的内存阻塞操作。
- query_cache_limit:MySQL 可以查询的最大查询结果数。如果查询结果大于该值,则不会存储。由于查询缓存在数据库创建后就开始尝试加载数据库,因此在返回所有响应之前,MySQL 并不知道是否超出了查询响应限制。只有完成此操作后,结果才会从查询缓存中删除。
优化查询缓存是提高数据库性能的重要组成部分。试用过程与下图相同。
缓存命中率可以使用以下公式计算:Qcache_hits/(Qcache_hits + Com_select)。
解析和预处理
解析器通过关键字对SQL语句进行解码,并创建相应的解析树。 MySQL 解析器将使用 MySQL 语法规则验证和解析查询。预处理器根据某些MySQL规则进一步检查解析日志是否合法,例如检查数据库表和数据列是否存在,以及检查名称和别名是否存在歧义。
查询优化器
查询优化器将解析树转换为执行计划。该请求可以通过多种方式执行,所有方式都返回相同的结果。优化器的任务就是在其中找到最好的执行计划。创建执行计划的过程将花费大量时间,尤其是当执行计划可用时。如果该SQL语句在执行过程中缓存了该SQL语句对应的最后一个执行计划,那么当类似的语句重新进入服务器时,可以直接使用缓存的执行计划,绕过执行过程。 SQL。陈述。流程,可以提高公告速度。
MySQL 使用基于成本的优化器(CBO)。它尝试使用某些执行计划来预测查询的成本,并选择成本最低的一个。优化器将根据优化规则转换关系表示。这里的转换是指一个关系表达式经过优化规则后会生成另一个关系表达式。同时,原始语言将被保留。经过多次转换,会产生多个执行计划,然后CBO会根据统计信息和成本模型(Cost Model)计算每个执行计划的成本,并选择成本最小的执行计划。从上面可以看出,CBO中有两个依赖项:统计信息和定价模型。统计信息是否准确、成本模型是否合理将影响CBO选择最佳方案。优化器的规则非常复杂,这里不再详细解释。您可以自己学习它们。
查询执行引擎
在分析和优化的过程中,MySQL会根据查询创建一个执行计划,MySQL查询执行引擎根据这个计划完成整个查询(即kill)。这里的执行计划是一个数据结构,而不是创建对应其他相关数据的字节码。
将结果返回给客户端
如果查询是可缓存的,MySQL会在这一阶段将结果存储在查询缓存中。一步步。当查询生成第一个响应时,MySQL就可以开始慢慢地将响应集返回给客户端。
作者:ztwindy
链接:https://juejin.im/post/5b7036de6fb9a009c40997eb
来源:掘金
如需商业印刷,请联系作者获得许可。非商业转载请注明来源。
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。