MySQL 高级原理: MySQL执行过程及执行顺序

2023-10-26

一、MySQL执行过程

MySQL整体的执行过程如下图所示

MySQL执行过程

1.1 连接器

1.1.1连接器的主要职责

1、负责与客户端的通信,是半双工模式,这就意味着某一固定时刻只能由客户端向服务器请求或者服务器向客户端发送数据,而不能同时进行,其中MySQL在与客户端连接TCP/IP的。

2、验证请求用户的账户和密码是否正确,如果账户和密码错误,会报错:Access denied for user 'root'@'localhost' (using password: YES)

3、如果用户的账户和密码验证通过,会在MySQL自带的权限表中查询当前用户的权限。

MySQL中存在4个控制权限的表,分别为user表,db表,tables_priv表,columns_priv表:

  • user表:存放用户账户信息以及全局级别(所有数据库)权限,决定了来自哪些主机的哪些用户可以访问数据库实例
  • db表:存放数据库级别的权限,决定了来自哪些主机的哪些用户可以访问此数据库
  • tables_priv表:存放表级别的权限,决定了来自哪些主机的哪些用户可以访问数据库的这个表
  • columns_priv表:存放列级别的权限,决定了来自哪些主机的哪些用户可以访问数据库表的这个字段

1.1.2 MySQL权限表的验证过程

1、 先从user表中的Host,User,Password这3个字段中判断连接的IP、用户名、密码是否存在,存在则通过验证。

2、通过身份认证后,进行权限分配,按照user,db,tables_priv,columns_priv的顺序进行验证。即先检查全局权限表user,如果user中对应的权限为Y,则此用户对所有数据库的权限都为Y,将不再检查db,tables_priv,columns_priv;如果为N,则到db表中检查此用户对应的具体数据库,并得到db中为Y的权限;如果db中为N,则检查tables_priv中此数据库对应的具体表,取得表中的权限Y,以此类推。

3、如果在任何一个过程中权限验证不通过,都会报错。

1.2 缓存

MySQL的缓存主要的作用是为了提升查询的效率,缓存以key和value的哈希表形式存储,key是具体的SQL语句,value是结果的集合。如果无法命中缓存,就继续走到分析器的这一步,如果命中缓存就直接返回给客户端。不过需要注意的是在MySQL的8.0版本以后,缓存被官方删除掉了。之所以删除掉,是因为查询缓存的失效非常频繁,如果在一个写多读少的环境中,缓存会频繁的新增和失效。对于某些更新压力大的数据库来说,查询缓存的命中率会非常低,MySQL为了维护缓存可能会出现一定的伸缩性的问题,目前在5.6的版本中已经默认关闭了,比较推荐的一种做法是将缓存放在客户端,性能大概会提升5倍左右。

1.3 分析器

分析器的主要作用是将客户端发过来的SQL语句进行分析,这将包括预处理与解析过程,在这个阶段会解析SQL语句的语义,并进行关键词和非关键词进行提取、解析,并组成一个解析树。具体的关键词包括不限定于以下:select/update/delete/or/in/where/group by/having/count/limit等。如果分析到语法错误,会直接给客户端抛出异常:ERROR:You have an error in your SQL syntax.

比如:select * from user where userId =1234;

在分析器中就通过语义规则器将select from where这些关键词提取和匹配出来,MySQL会自动判断关键词和非关键词,将用户的匹配字段和自定义语句识别出来。这个阶段也会做一些校验:比如校验当前数据库是否存在user表,同时假如user表中不存在userId这个字段同样会报错:unknown column in field list.

1.4 优化器

能够进入到优化器阶段表示SQL是符合MySQL的标准语义规则的并且可以执行的,此阶段主要是进行SQL语句的优化,会根据执行计划进行最优的选择,匹配合适的索引,选择最佳的执行方案。比如一个典型的例子是这样的:

表T,对A、B、C列建立联合索引,在进行查询的时候,当SQL查询到的结果是:select xx where B=x and A=x and C=x,很多人会以为是用不到索引的,但其实会用到,虽然索引必须符合最左原则才能使用,但是本质上,优化器会自动将这条SQL优化为:where A=x and B=x and C=X,这种优化会为了底层能够匹配到索引,同时在这个阶段是自动按照执行计划进行预处理,MySQL会计算各个执行方法的最佳时间,最终确定一条执行的SQL交给最后的执行器。

1.5 执行器

在执行器的阶段,此时会调用存储引擎的API,API会调用存储引擎,主要有以下存储的引擎,不过常用的还是myisaminnodb

img

引擎以前的名字叫做:表处理器(其实这个名字我觉得更能表达它存在的意义)负责对具体的数据文件进行操作,对SQL的语义比如select或者update进行分析,执行具体的操作。在执行完以后会将具体的操作记录到binlog中,需要注意的一点是:select不会记录到binlog中,只有update/delete/insert才会记录到binlog中。而update会采用两阶段提交的方式,记录都redolog中。

二、执行的状态

可以通过命令:show full processlist,展示所有的处理进程,主要包含了以下的状态,表示服务器处理客户端的状态,状态包含了从客户端发起请求到后台服务器处理的过程,包括加锁的过程、统计存储引擎的信息,排序数据、搜索中间表、发送数据等。囊括了所有的MySQL的所有状态,其中具体的含义如下图:

img

三、SQL的执行顺序

事实上,SQL并不是按照我们的书写顺序来从前往后、左往右依次执行的,它是按照固定的顺序解析的,主要的作用就是从上一个阶段的执行返回结果来提供给下一阶段使用,SQL在执行的过程中会有不同的临时中间表,一般是按照如下顺序:

img

img

例子:select distinct s.id from T t join S s on t.id=s.id where t.name="Yrion" group by t.mobile having count(*)>2 order by s.create_time limit 5;

这里有几个需要注意的地方:

1、SQL语句是从FROM开始执行的,而不是SELECT。MySQL在执行SQL查询语句的时,首先是将数据从硬盘加载到数据缓冲区中,以便对这些数据进行操作。

2、SELECT是在FROM和GROUP BY 之后执行的。这就导致了无法在WHERE中使用SELECT中设置字段的别名作为查询条件。

3、UNION是排在ORDER BY之前的。虽然数据库允许SQL语句对UNION段中的子查询或者派生表进行排序,但是这并不能说明在 UNION 操作过后仍保持排序后的顺序。

4、在MySQL中SQL的逻辑查询是根据上述进行查询,但MySQL可能并不完全会按照逻辑查询处理方式进行查询。MySQL有2个组件:

​ 1)分析SQL语句的Parser;

​ 2)优化器Optimizer;

MySQL在执行查询之前,都会选择一条自认为最优的查询方案去执行,获取查询结果。一般情况下都能计算出最优的查询方案,但在某些情况下,MySQL给出的查询方案并不是很好的查询方案。

5、存在索引时,优化器优先使用索引的插叙条件,当索引为多个时,优化器会直接选择效率最高的索引去执行。

四、SQL语句where后条件执行先后顺序

4.1 结论

  • 针对MySQL,其条件执行顺序是 从左往右,自上而下。
  • 针对Orcale,其条件执行顺序是从右往左,自下而上。

4.2 MySQL

MySQL where执行顺序是从左往右执行的,在数据量小的时候不用考虑,但数据量多的时候要考虑条件的先后顺序,此时应遵守一个原则:排除越多的条件放在第一个。

在用MySQL查询数据库的时候,连接了很多个过滤条件,发现非常慢。例如:select… where p.languages_id=1 and t.type=1 and p.products_id in(472,474),,这样查询需要20多秒,虽然在各个字段上都建立了索引。用分析Explain SQL一分析,发现在第一次分析过程中就返回了几万条数据:where d p.languages_id=1 ,然后再依次根据条件缩小范围。

然后稍微改变一下where字段的位置之后,速度就有了明显地提高:where p.products_id in(472,474) and p.languages_id=1 and t.type=1,这样第一次的过滤条件是p.products_id in(472,474),它返回的结果只有不到10条,接下来还要根据其它的条件来过滤,自然在速度上有了较大的提升。经过实践发现,不要以为where中的字段顺序无所谓,可以随便放在哪,应该尽可能地第一次就过滤掉大部分无用的数据,只返回最小范围的数据。

大多时候MySQL会自动根据SQL语句做出优化,使用最优的SQL语句进行查询。有时候MySQL无法根据SQL语句做出最优的优化顺序,所以还是要我们自己预判断出哪种过滤是最优,毕竟自己才最懂自己的数据。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MySQL 高级原理: MySQL执行过程及执行顺序 的相关文章

  • 如何创建具有两个主键和两个外键的表?

    create table Machine Machine ID int primary key Machine Name varchar 30 Machine Title varchar 30 create table Part Part
  • 标签系统:Toxi 解决方案问题

    我对标签数据库模式的 Toxi 解决方案感到有点困惑 我正在开发一个系统 用户可以向该系统提交项目 并且这些项目可以具有与其关联的标签 在阅读了 tagchemas 后 我发现 Toxi 解决方案最适合我的需求 但是 我不完全确定我的计划是
  • CodeIgniter 中使用 Active Record 的查询中的 DATE_FORMAT 不起作用

    编码员 我在这里遇到一个小问题 找不到解决方案 我正在使用 CI 的 Active Record 构建查询 这是查询的代码 this gt db gt select u id AS user id u email p display nam
  • 在 MySQL 中存储 IPv6 地址

    正如 需要支持 ipv6 的 inet aton 和 inet ntoa 函数 http bugs mysql com bug php id 34037 目前没有用于存储 IPv6 地址的 MySQL 函数 用于存储 插入的推荐数据类型 函
  • 使用日期作为窗口函数实现 RANGE

    从 SQLAlchemy 1 4 25 开始 没有内置支持 所以我尝试使用该解决方案here https stackoverflow com a 69606048 11277108 这是我的复制 from datetime import d
  • 如何获取MySQL中最后更新的行的ID?

    如何使用 PHP 获取 MySQL 中最后更新行的 ID 我找到了这个问题的答案 SET update id 0 UPDATE some table SET column name value id SELECT update id id
  • 如何通过python将python字典存储到mysql数据库中

    我试图通过将字典转换为字符串然后尝试插入来将以下字典存储到 mysql DB 中 但出现以下错误 如何解决这个问题 或者有其他方法将字典存储到 mysql DB 中吗 dic office component office Word2010
  • CentOs Php 和 MySql 配置

    我已经安装了 php 并运行了一段时间 但我开始从事一个连接到数据库 即 mysql 的项目 所以我安装了 mysql 5 1 73 现在当我使用它连接到数据库时线 dbhandle mysql connect hostname usern
  • sqlalchemy:每次提交都需要回滚吗?

    我正在为我的网络应用程序使用 SQLAlchemy 我见过很多这样的代码 try session commit except session rollback 我想知道是否每个人都有必要commit 手术 如果是 那么为什么它不属于comm
  • 用于从 PHP 更新实时
  • 的 jQuery 插件
  • 有没有任何 jQuery 插件可以创建类似实时 feed 的东西推特主页 http www twitter com 使用 PHP 它从 MySQL 数据库获取数据 PHP 文件必须如何 Thanks 您确实不需要为此使用插件 您可以使用 j
  • 课程完成时更新外部数据库

    我的场景 Moodle 中的用户完成了一门课程 一旦发生这种情况 我想更新外部数据库 我的理解是 每次运行 cron 作业时都会触发 course completed 事件 使用一些简单值 例如已完成课程的用户名 ID 课程 ID 以及完成
  • mysql连接3个表

    如何连接三个具有一个公共列 id 的mysql表 例如 从表1中选择a b 从表2中选择c d 从表3中选择e f 其中id x 谢谢 SELECT t1 a t1 b t2 c t2 d t3 e t3 f FROM table1 t1
  • 如何在codeigniter中从数据库返回最后一条记录?

    我正在尝试获取我拥有数据的最后日期 所以我想打印 date data 列中的最后一个日期 在模型中 public function last record query this gt db gt select LAST date data
  • 使用带有 ORDER 子句的 AES_DECRYPT 在 MySQL 中返回 BLOB 数据

    我正在创建一个系统 用户可以在其中通过 PHP 和 MySQL 数据库存储消息 并且我使用 MySQL AES ENCRYPT 函数来加密这些消息的内容 这是我的posts table CREATE TABLE IF NOT EXISTS
  • 使用存储的日期字段来计算计算当前过去天数的字段

    我正在使用 MySQL 和 phpMyAdmin 我的数据库中有一个 日期 字段 我需要在 MySQL db 中创建一个字段 该字段将计算并显示自每个记录 行的 日期 字段中的日期以来已经过去的天数 我没有能力使用 PHP 即时生成代码 有
  • 我怎样才能找出MySQL中的默认字符集/排序规则[重复]

    这个问题在这里已经有答案了 我在 Ubuntu 18 04 上使用 MySQL 和 MySQL Workbench 8 0 当我创建字符串类型的列时 我将字符集 排序规则保留为默认值 在 MySQL Workbench 中 它只是告诉我就是
  • 小写表名错误

    我正在尝试设置lower case table name价值2 因为它是 Windows 服务器 但是当我启动 MySQL Workbench 并连接到我的服务器时 出现以下错误 服务器所在的系统不能正确支持所选的lower case ta
  • ? LIKE(列 || '%')

    我可以有这样的条件吗 SELECT FROM table WHERE LIKE column 哪里的 是一个字符串参数值 例如 这些参数值 当列等于时应返回 true admin products admin products 1 admi
  • 我可以在 MySQL 中存储图像吗?

    这个问题在这里已经有答案了 可能的重复 MySQL 中的图像 https stackoverflow com questions 1665730 images in mysql 在 MySQL 中存储图像 https stackoverfl
  • cron 作业或 PHP 调度程序

    我使用 MYSQL 作为我的数据库 PHP 作为我的编程语言 我想运行一个 cron 作业 该作业将运行直到当前系统日期与我的数据库表中名为 PROJECT 的 截止日期 日期 列匹配 一旦日期相同的是 必须运行更新查询 这会将状态 项目表

随机推荐

  • java 百度ocr文字识别_最简单调用百度OCR接口实现文字识别技术

    Java 纯文本查看 复制代码package baiduocr import java util HashMap import org json JSONObject import com baidu aip ocr AipOcr publ
  • npm install生成的package-lock.json文件有什么作用?

    一 package json node modules package lock json是什么 package json里面定义的是版本范围 比如 1 0 0 具体跑npm install的时候安的什么版本 要解析后才能决定 这里面定义的
  • OpenCV4 Android 调用摄像头

    OpenCV4 调用摄像头黑屏问题 OpenCV 调用 Android 摄像头这一块 我之前研究了好几天 都是一片黑 毫无头绪 后来发现 OpenCV4 要想调用摄像头 必须继承自 OpenCV 的 CameraActivity Camer
  • 英语(2)-- 实用口语100句

    Any day will do 哪一天都可以 Any messages for me 有我的留言吗 Are you by yourself 你一个人来吗 All right with you 你没有问题吧 Are you free tomo
  • background-position-x的兼容性问题

    在firefox中 不支持background position x和background position y属性 在ie chrome等流览器则支持该属性 为兼容firefox和 ie 需要将此属性改写成 background posi
  • IIS 日志解析,增强 IIS 服务器安全性

    企业严重依赖 Microsoft Internet 信息服务 IIS 服务器来托管其网页和 Web 应用程序 以及存储其文件 请务必妥善保护您的 IIS 服务器 包括 Web 和 FTP 什么是 IIS 日志 IIS 日志是 Microso
  • MATLAB神经网络43个案例分析——BP网络数据分类

    小论文 主要工作 BP神经网络MATLAB实现 这个例子有24个特征 网络是24 25 4的结构 详细了解程序 看明白了并且用matlab看变量的变化 加深了理解 后续目标 自己写出一个训练BP的网络 测试成功率 加深理解 便于后期自己制作
  • Unity开发(一)——各种坑集合

    1 unity的vs项目无法打开 2 不安全代码只会在使用 unsafe 编译的情况下出现 3 unity各菜单含义
  • Oracle查看总数据量大小

    Oracle查看总数据量大小 select round sum bytes 1024 1024 1024 total data size from dba segments where segment name not like BIN
  • SqlServer的bit类型

    SqlServer的bit类型比较特殊 在SQL Server 中 图形化界面时 显示的是true false 输入也是true false 用T SQL语句select查询出来的结果是1 0 使用T SQL语句时可以用1 0 也可以用tr
  • 王峰十问Nervos联合创始人王宁宁:缘何“中国最懂以太坊的人”要走中国公链的自主创新之路?...

    本文旨在传递更多市场信息 不构成任何投资建议 文 王峰十问 出品 火星财经APP ID hxcj24h 11月7日晚8点 王峰十问第36期 惊蛰 中国公链如何实现自主创新 在火星财经社群展开 这也是 王峰十问中国公链 系列正式启动的第1期
  • 博易大师行情服务器文件夹,博易大师目录

    c program files pobo settings这个目录下的东西是pobo的参数设置这个路径是可以改的具体在pobo安装路径下有个cfg子目录里面有个userpath ini文件内容就是pobo settings的生成路径第一次运
  • TCP 多线程——一个服务器被多个客户端连接

    为了使一个服务器端能被多个客户端连接我们采用线程的方法 服务器创建一个线程之后 打开的套接字就被线程所继承 线程可以和连接的客户进行通信 而主线程 主服务器 可以继续接受以后的客户连接 即Accept之后产生一个c 然后将c传递给新创建线程
  • Visual C++ 2008 Feature Pack 开发包

    http download csdn net detail fandh 1018063 Visual C 2008 Feature Pack 开发包
  • 使用 Skeleton Screen 提升用户感知体验

    1024程序猿节 愿世界和平 没有bug 腾讯云社区向改变世界的程序猿致敬 作者 陈纬杰 一直以来 无论是web还是iOS android的应用中 为了提升应用的加载等待这段时间的用户感知体验 各种奇门遁甲之术层出不穷 其中 菊花图以及由它
  • 【满分】【华为OD机试真题2023 JAVA&JS】硬件产品销售方案

    华为OD机试真题 2023年度机试题库全覆盖 刷题指南点这里 硬件产品销售方案 知识点递归数组DFS搜索回溯 时间限制 1s 空间限制 256MB 限定语言 不限 题目描述 某公司目前推出了AI开发者套件 AI加速卡 AI加速模块 AI服务
  • 可以改动的option组件_MySQL的validate_password插件/组件总结

    Password Validation插件和组件 在MySQL 8 0之前 MySQL使用的是validate password插件 plugin 检测 验证账号密码强度 保障账号的安全性 而到了MySQL 8 0 引入了服务器组件 Com
  • c高级 day4

    实现一个对数组求和的函数 数组通过实参传递给函数 bin bash read p 请输入数组 a arr function sum sum 0 for i in arr do sum sum i done echo 数组和 sum sum
  • ubuntu nginx服务器安装SSL证书

    证书安装 前往 SSL 证书管理控制台中下载 SSL 证书 名称以 bdjw work 为例 文件压缩包 并解压到本地目录 解压缩后 可获得相关类型的证书文件 文件内容 bdjw work bundle crt 证书 bdjw work k
  • MySQL 高级原理: MySQL执行过程及执行顺序

    一 MySQL执行过程 MySQL整体的执行过程如下图所示 1 1 连接器 1 1 1连接器的主要职责 1 负责与客户端的通信 是半双工模式 这就意味着某一固定时刻只能由客户端向服务器请求或者服务器向客户端发送数据 而不能同时进行 其中My